@synthesize obj=_obj的意义详解 @property和@synthesize

来源:互联网 发布:python 定义一个list 编辑:程序博客网 时间:2024/05/06 07:50

 AppDelegate 常看见如下写法: 

    常看见:  @synthesize window=_window;   意思是说,window 属性为 _window 实例变量合成访问器方法。     

     解析: 

            意思是说window属性生成存取方法 :setWindow方法,而这个方法就是实际变量 _window的 的存取方法,setwindow操作的就是_window这个方法。

       PS:window是属性,而_window是实际的变量

      注意:通过这个看似是赋值的这样一个操作,我们可以在@synthesize 中定义与变量名不相同的getter和setter的命名,籍此来保护变量不会被不恰当的访问。


   常见两种写法:

  一: 

    

@interface MyClass:NSObject{    

        MyObjecct *_myObject;  

}  

@property(nonamtic, retain) MyObjecct *myObject;  

@end  

  

@implementatin MyClass  

@synthesize myObject=_myObject;  

二: 

 

@interface MyClass:NSObject{  

        

}  

@property(nonamtic, retain) MyObjecct *myObject;  

@end  

  

@implementatin MyClass  

@synthesize myObject=_myObject;  


  这个类中声明了一个变量_myObject,又声明了一个属性叫myObject,然后用@synthesize生成了属性myObject的存取方法,这个存取方法的名字应该是:setmyObject和getmyObject。@synthesize myObject=_myObject的含义就是属性myObject的存取方法是做用于_myObject这个变量的。这种用法在Apple的Sample Code中很常见。


 从上面我们就应该清楚:  是的,myObject是属性,而_ myObject才是变量,我们最终操作的变量都是_myObject。 

  

实例解析: 


C代码  1:


self.nameVarPtr = [[ObjectName alloc] init]   

 
C代码  2:

nameVarPtr = [[ObjectName alloc] init] 

解刨: 


      self.nameVarPtr=xxx 这种赋值方式等价于调用 [self setnameVarPtr:xxx], 而setnameVarPtr:xxx的方法的实现又是依赖于@property的属性的,比如retain,assign等属性。

      nameVarPtr = xxx 的赋值方式,仅仅是对一个指针进行赋值。nameVarPtr仅仅是一个指针变量,记录了xxx的地址。在这个过程中不会调用setter方法,不会调用setter方法,就和@property没有关系,从而,也和retain,assign等属性没有关系。这种赋值方式就是一个简单的指针赋值。


综上,对成员变量进行赋值,为防内存泄露需要注意的点:


1.self调用setter方法的方式

ObjectName*  tmp= [[ObjectName alloc] init];

self.nameVarPtr =tmp;                 //retainCount=2

[tmp release];                               //retainCount=1


2.指针赋值方式,不会调用setter方法

nameVarPtr= [[ObjectName alloc] init]; // retainCount=1

所以: 建议如下 :

大家在对某个变量进行赋值操作的时候,尽量要写self.myObj = xxx; 这才是最可靠的方法。


@property属性只是普及 ;


readwrite:这个属性是默认的情况,会自动为你生成存取器

assign:这个属性一般用来处理基础类型,比如int、float等等,如果你声明的属性是基础类型的话,assign是默认的,你可以不加这个属性

natomic:默认是有该属性的,这个属性是为了保证程序在多线程情况,编译器会自动生成一些互斥加锁代码,避免该变量的读写不同步问题

readonly:只生成getter不会有setter方法

copy:这个会自动生成你赋值对象的克隆,相当于在内存中新生成了该对象的副本,这样一来,改变赋值对象就不会改变你声明的这个成员变量了

retain: 会自动retain赋值对象  指定retain应该在后面的对象上调用,前一个值发送一条release消息。你可以想象一个NSString实例,它是一个对象,而且你可能想要retain它。释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1 ,使用retain: 对其他NSObject和其子类 ,retain,是说明该属性在赋值的时候,先release之前的值,然后再赋新值给属性,引用再加1。

nonatomic:如果该对象无需考虑多线程的情况,请加入这个属性,这样会让编译器少生成一些互斥加锁代码,可以提高效率  保证setter/getter的原子性,多线程情况下数据可能会有问题。nonatomic,非原子性访问,不加同步,多线程并发访问会提高性能。

atomic:对于对象的默认属性,就是setter/getter生成的方法是一个原子操作。如果有多个线程同时调用setter的话,不会出现某一个线程执行setter全部语句之前,另一个线程开始执行setter的情况,相关于方法头尾加了锁一样。



转帖:http://blog.csdn.net/chengwuli125/article/details/8677036

0 0
原创粉丝点击