定义属性中的特性有atomic、nonatomic、copy、assign、strong、weak等,一般格式如下:
atomic:
默认属性。
当前进程进行到一半时,其他线程访问当前线程,可保证先执行完当前线程。
只保证setter/getter完整,即读写安全(使用了自旋锁(原子操作),确保线程同步),不是线程安全。
nonatomic:
非默认属性。
两个线程同时访问同一个属性将会导致无法预计的结果。
优点是程序运行速度快。
copy:
是owner,不是reference。当对象可变时,可设为copy,用于获取此值的副本。
新的对象引用计数为1,与原始对象引用计数无关,且原始对象引用计数不会改变。
使用copy创建的新对象也是强引用,使用完后需要释放掉该对象。
copy特性可以减少对象对上下文的依赖。新对象、原始对象中任一对象的值改变不会影响另一对象的值。
要想设置该对象的特性为copy,该对象必须遵守NSCopying协议,Foundation类默认实现了NSCopying协议,只需要为自定义的类实现该协议即可。
assign:
与copy相反,只是reference(引用),不是owner(所有者),只返回指针。
用于CGFloat、NSInteger、BOOL等类型。
释放后再发送消息会导致程序崩溃。
strong:
默认属性。
strong == retain,iOS引入ARC后,用strong替代了retain。
创建一个强引用的指针,引用对象的引用计数加1。
strong特性表示两个对象内存地址相同(建立一个指针,进行指针拷贝),内容会一直保持相同,直到变更一个对象的内存地址,或将其设置为nil。
如果有多个对象同时引用一个属性,任一对象对该属性的修改都会影响其他对象获取的值。
所有实例变量、局部变量默认都是strong。
weak:
只是reference(引用),不是owner(所有者),即引用计数不会加1。
可将weak对象设为nil,向nil发送消息,什么都不会执行,程序也不会崩溃。
代理使用weak。delegate几乎一直own代理对象,所以代理对象应该对代理使用weak,否则会形成循环引用(retain cycle)。但也有例外,如果代理对象的生命周期比代理短,代理对象也可以使用strong。
IBOutlet常用weak。
readonly:
非默认属性。
只有可读方法,即getter方法。
readwrite:
默认属性。
若希望属性只允许自己读写,而对所有外部文件都是只读的,那么可以在接口的位置声明该属性为readonly类型,在私有接口的位置重新该属性为readwrite类型。
有关strong与weak对比的生动形象例子!
假设对象是一条小狗,小狗想跑走(be deallocated)。
strong类型就像是拴狗的绳子,只要有一条绳子栓住狗,它就不能跑走,如果有五条绳子拴着同一条狗(五个strong类型指向同一个对象),只有当五条绳子都释放狗才可以跑走。
weak类型就像是小孩子看着小狗说:看这里有小狗。只要还有绳子拴着小狗,小孩子们就可以继续指着小狗说:看这里有小狗。当绳子释放了的时候,不管有多少小孩子依旧在指着小狗说:看这里的小狗。小狗都会跑掉。
当最后一个strong指针不再指向这个对象,这个对象就会被释放,此时所有指向这个对象的weak指针都将被清空。
参考:
网友评论