您的位置:首页 > 运维架构

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

2014-05-29 17:12 375 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: