synthesize与dynamic
@property有两个对应的词,一个是 @synthesize,一个是 @dynamic。如果 @synthesize和 @dynamic都没写,那么默认的就是@syntheszie var = _var;
在Xcode4.5和以后的版本中,可以省略@synthesize,编译器会自动加上setter和getter方法的实现。并且默认会去访问_var这个成员变量,如果找不到_var这个成员变量,会自动生成一个叫做_var的私有成员变量。
@synthesize 的语义是如果你没有手动实现 setter 方法和 getter 方法,那么编译器会自动为你加上这两个方法。
@dynamic 告诉编译器:属性的 setter 与 getter 方法由用户自己实现,不自动生成。(当然对于 readonly 的属性只需提供 getter 即可)。若未实现属性的 setter 与 getter,编译期间不会报错,在使用到该属性的setter 与 getter时将崩溃,因为@dynamic 指定属性的setter 与 getter是动态绑定的。
nonatomic与atomic
iOS开发中使用@property声明属性时,经常用到atomic与nonatomic两个关键字
- atomic系统自动生成的getter/setter方法会进行加锁操作
- nonatomic系统自动生成的getter/setter方法不会进行加锁操作
atomic
系统生成的 getter/setter 会保证 get、set 操作的完整性,不受其他线程影响。getter 还是能得到一个完好无损的对象(可以保证数据的完整性),但这个对象在多线程的情况下是不能确定的。
比如:
- 如果当一个线程正在get或set时,又有另一个线程同时在进行release操作,可能会直接crash
- 如果线程 A 调了 getter,与此同时线程 B 、线程 C 都调了 setter——那最后线程 A get 到的值,有3种可能:可能是 B、C set 之前原始的值,也可能是 B set 的值,也可能是 C set 的值。同时,最终这个属性的值,可能是 B set 的值,也有可能是 C set 的值。所以atomic可并不能保证对象的线程安全。
nonatomic
系统生成的getter/setter方法没有加锁,线程不安全,但更快。当多个线程同时访问同一个属性,会出现无法预料的结果。
属性weak、nonatomic、strong、readonly等介绍
readwrite与readonly
readwrite:这个属性是默认的情况,会自动为你生成存取器。
readonly:只生成getter不会有setter方法。
readwrite、readonly这两个属性的真正价值,不是提供供成员变量访问接口,而是控制成员变量的访问权限。
strong与weak(弱引用)
strong:强引用,也是我们通常说的引用,其存亡直接决定了所指向对象的存亡。如果不存在指向一个对象引用,
并且此对象不在显示在列表中,则此对象会被从内存中释放。
weak:弱引用,不决定对象的存亡。即使一个对象被持有无数个弱引用,只要没有强引用指向它,那么还是会被清除。
strong与retain功能相似;weak与assign相似,只是当对象消失后weak会自动把指针变为nil。
assign、copy、retain
assign:默认类型,setter方法直接赋值,不进行任何retain操作,不改变引用计数。一般用来处理基本数据类型。
retain:释放旧的对象(release),将旧对象的值赋给新对象,再令新对象引用技术为1。我理解为指针的拷贝,拷贝一份原来
的指针,释放原来指针指向的对象内容,再令指针指向新的对象内容。
copy:与retain处理流程一样,先对旧值release,再copy出新的对象,retainCount为1。为了减少对上下文的依赖而引入的机制。