iOS何时使用self

来源:互联网 发布:影楼后期设计软件 编辑:程序博客网 时间:2024/06/05 05:10

何时使用self.在网上搜索或者论坛里的回复大多都是简简单单的说这与objc的存取方法有关,如何与存取方式有关究竟他们之间的是什么样的关系就很少有同学回答了。下面以代码来说明问题:

创建一个Student类,继承NSObject类,代码:

<span class="lnum" style="margin: 0px; padding: 0px;">   1:  </span>#import <Foundation/Foundation.h>
   2:   
<span class="lnum" style="margin: 0px; padding: 0px;">   3:  </span>@<span class="kwrd" style="margin: 0px; padding: 0px;">interface</span> Student : NSObject{
   4:   
<span class="lnum" style="margin: 0px; padding: 0px;">   5:  </span>    NSString *idd;
   6:      NSString *name;
<span class="lnum" style="margin: 0px; padding: 0px;">   7:  </span>}
   8:  @property (nonatomic, retain) NSString *idd;
<span class="lnum" style="margin: 0px; padding: 0px;">   9:  </span>@property (nonatomic, retain) NSString *name;
  10:   
<span class="lnum" style="margin: 0px; padding: 0px;">  11:  </span>@end

.m文件 代码:

<span class="lnum" style="margin: 0px; padding: 0px;">   1:  </span>#import <span class="str" style="margin: 0px; padding: 0px;">"Student.h"</span>
   2:   
<span class="lnum" style="margin: 0px; padding: 0px;">   3:  </span>@implementation Student
   4:  @synthesize idd,name;
<span class="lnum" style="margin: 0px; padding: 0px;">   5:  </span> 
   6:  - (void)dealloc
<span class="lnum" style="margin: 0px; padding: 0px;">   7:  </span>{
   8:      [idd release];
<span class="lnum" style="margin: 0px; padding: 0px;">   9:  </span>    [name release];
  10:      [super dealloc];
<span class="lnum" style="margin: 0px; padding: 0px;">  11:  </span>}
  12:   
<span class="lnum" style="margin: 0px; padding: 0px;">  13:  </span> 
  14:  @end

使用@propety @synthesize实现Student的成员属性的set get方法。通常我们在其他类里访问Student的成员属性的做法:

获取student的名字通过student.name,给名字赋值[student setName:@“jordy”]; 其中studentStudent类对象,如果在Student类内部访问其成员属性使用[self setName:@”jordy”], 访问使用self.name;

注意:上述的代码,由于wordpress的原因,代码中的字符会自动保存为中文格式。你在使用时记得改为英文格式。

Student.hStudent.m文件,是我们习惯性的写法,但似乎还是不能解释什么加self和不加self的区别,请看下面代码,是另一种习惯性的写法,还以Student类为例:

.h文件 代码:

<span class="lnum" style="margin: 0px; padding: 0px;">   1:  </span>#import <Foundation/Foundation.h>
   2:   
<span class="lnum" style="margin: 0px; padding: 0px;">   3:  </span>@<span class="kwrd" style="margin: 0px; padding: 0px;">interface</span> Student : NSObject{
   4:   
<span class="lnum" style="margin: 0px; padding: 0px;">   5:  </span>    NSString *_idd;
   6:      NSString *_name;
<span class="lnum" style="margin: 0px; padding: 0px;">   7:  </span>}
   8:  @property (nonatomic, retain) NSString *idd;
<span class="lnum" style="margin: 0px; padding: 0px;">   9:  </span>@property (nonatomic, retain) NSString *name;
  10:   
<span class="lnum" style="margin: 0px; padding: 0px;">  11:  </span>@end

 

.m文件 代码:

<span class="lnum" style="margin: 0px; padding: 0px;">   1:  </span>#import <span class="str" style="margin: 0px; padding: 0px;">"Student.h"</span>
   2:   
<span class="lnum" style="margin: 0px; padding: 0px;">   3:  </span>@implementation Student
   4:  @synthesize idd = _idd;
<span class="lnum" style="margin: 0px; padding: 0px;">   5:  </span>@synthesize name = _name;
   6:   
<span class="lnum" style="margin: 0px; padding: 0px;">   7:  </span>- (<span class="kwrd" style="margin: 0px; padding: 0px;">void</span>)dealloc
   8:  {
<span class="lnum" style="margin: 0px; padding: 0px;">   9:  </span>    [_idd release];
  10:      _idd = nil;
<span class="lnum" style="margin: 0px; padding: 0px;">  11:  </span>    [_name release];
  12:      _name = nil;
<span class="lnum" style="margin: 0px; padding: 0px;">  13:  </span>    [super dealloc];
  14:  }
<span class="lnum" style="margin: 0px; padding: 0px;">  15:  </span> 
  16:   
<span class="lnum" style="margin: 0px; padding: 0px;">  17:  </span>@end
 

可以注意到上述代码,与之前的代码,在.h文件name变量改写为了_name;在.m文件中@sythesize的写法也发生了变化。

如果通过方法self._name获取属性的值,xcode编译器会提示错误,其实这也就说明了,我们通常使用self.name实际使用的是studentnameget方法,同理nameset方法亦是如此。

 

接下来从内存管理来说明使用self.和不使用self的区别:

ViewController.h文件,使用Student类,代码如下:

<span class="lnum" style="margin: 0px; padding: 0px;">   1:  </span>#import <UIKit/UIKit.h>
   2:  @class Student;
<span class="lnum" style="margin: 0px; padding: 0px;">   3:  </span> 
   4:  @interface ViewController : UIViewController{
<span class="lnum" style="margin: 0px; padding: 0px;">   5:  </span>    
   6:      Student *_student;
<span class="lnum" style="margin: 0px; padding: 0px;">   7:  </span>}
   8:   
<span class="lnum" style="margin: 0px; padding: 0px;">   9:  </span>@property (nonatomic, retain) Student *student;
  10:   
<span class="lnum" style="margin: 0px; padding: 0px;">  11:  </span>@end

ViewController.m文件,代码:

<span class="lnum" style="margin: 0px; padding: 0px;">   1:  </span>#import <span class="str" style="margin: 0px; padding: 0px;">"ViewController.h"</span>
   2:  #import "Student.h"
<span class="lnum" style="margin: 0px; padding: 0px;">   3:  </span> 
   4:  @implementation ViewController
<span class="lnum" style="margin: 0px; padding: 0px;">   5:  </span>@synthesize student = _student;
   6:   
<span class="lnum" style="margin: 0px; padding: 0px;">   7:  </span>- (<span class="kwrd" style="margin: 0px; padding: 0px;">void</span>)didReceiveMemoryWarning
   8:  {
<span class="lnum" style="margin: 0px; padding: 0px;">   9:  </span>    [super didReceiveMemoryWarning];
  10:  }
<span class="lnum" style="margin: 0px; padding: 0px;">  11:  </span> 
  12:  #pragma mark - View lifecycle
<span class="lnum" style="margin: 0px; padding: 0px;">  13:  </span> 
  14:  - (void)viewDidLoad
<span class="lnum" style="margin: 0px; padding: 0px;">  15:  </span>{
  16:      [super viewDidLoad];
<span class="lnum" style="margin: 0px; padding: 0px;">  17:  </span>}
  18:   
<span class="lnum" style="margin: 0px; padding: 0px;">  19:  </span>- (<span class="kwrd" style="margin: 0px; padding: 0px;">void</span>) dealloc
  20:  {
<span class="lnum" style="margin: 0px; padding: 0px;">  21:  </span>    [_student release];
  22:      _student = nil;
<span class="lnum" style="margin: 0px; padding: 0px;">  23:  </span>    [super dealloc];
  24:  }

其它的方法没有使用到,所以这里就不在显示了。

ViewController.mviewDidLoad方法中创建一个Student类的对象

<span class="lnum" style="margin: 0px; padding: 0px;">   1:  </span>Student *mystudent = [[Student alloc] init];
   2:  self.student = mystudent;
<span class="lnum" style="margin: 0px; padding: 0px;">   3:  </span>[mystudent release];

这是相信有人会有疑问了,问什么创建student对象要这么复杂,似乎直接使用self.student = [[Student alloc] init]; 也没有问题,不加self有时也是挺正常的呀

接下来就需要从内存角度来分析它们之间的区别了:

1、加self的方式:

Student *mystudent = [[Student alloc] init];       //mystudent 对象 retainCount = 1;

self.student = mystudent;   //student 对象 retainCount = 2;

[mystudent release];  //student 对象 retainCount = 1;

retainCount指对象引用计数,student的property 是retain 默认使用self.student引用计数+1。

2、不加self的方式

Student *mystudent = [[Student alloc] init];       //mystudent 对象 retainCount = 1;

student = mystudent;   //student 对象 retainCount = 1;

[mystudent release];   //student 对象内存已释放,如果调用,会有异常

3、加self直接赋值方式

self.student = [[Student alloc] init];  //student 对象 retainCount = 2;容易造成内存泄露

由于objective-c内存管理是根据引用计数处理的,当一个对象的引用计数为零时,gcc才会释放该内存。

 转载:http://jordy.easymorse.com/?p=805
 
个人总结只需要在属性初始化的时候使用self.属性,其他时候直接使用属性名就行;使用self.是 使retaincount+1,为了确保当前类对此属性具有拥有权
个人使用习惯:
复制代码
@interface CustomClass : UIViewController{    NSString *str}@property (retain, nonatomic) NSString *str;@implementation CustomClass@synthesize str;-(void)viewDidLoad{    //方法一  用alloc必须手动释放一次    self.str  =  [[NSString alloc]initWithString:@"my str"];     [str release];    //方法二 用类方法不用   self.str =     [NSString stringWithString:@"my str"];    以后调用时直接使用str,不必使用self.str   [str appendString:@"\n"];}//在dealloc中必须释放- (void)dealloc{    //方法一    [str release];    str = nil;    //方法二    self.str = nil;    [super dealloc];}        
0 0