@property的常用属性关键字有nonatomic、atomic、readonly、writeonly、readwrite、assign、retain、copy、strong、weak、unsafe_unretained、nonnull、nullable、null_resettable,看着挺多的,但是经常用的也就那几个。
- atomic:默认关键字,也就是说如果什么都不写,默认就是这个。表示该属性是线程同步的。一般用不到,会影响性能。
- nonatomic:非线程同步。
- readwrite:可读写。
- readonly: 只能读不可写。
- writeonly: 只能写,不能读(get)。
- assign:默认关键字。非对象类型一般使用此关键字,简单赋值,不更改索引计数。
对基础数据类型 (例如NSInteger,CGFloat)和C数据类型(int, float, double, char, 等)。 - retain:对象的引用计数+1。ARC下已经不再使用此关键字,用strong代替。
- copy:拷贝一个新的对象,新对象的引用计数+1,原对象不变。
- strong: 使用了引用计数。
atomic&& nonatomic
atomic
- atomic会给属性加上一个同步锁, 这是为了防止多线程同时访问属性出现异常需要添加的属性, 但是这样会增加额外的内存开销 并且在变编程习惯中, 我们都应该避免多线程访问统一资源
- 即便是使用atomic, 在多线程时也无法完全保证线程安全, 往往是需要手动添加线程锁
nonatomic
- 非原子性, 即非线程安全的, 不给变量提供线程锁保护, 这样会提高性能
- 在iOS的移动端, 一般不会出现多线程访问同一个属性的情况, 就算发生情况, atomic也不能完美的保证安全, 并且还需要手动增加线程锁, 因此对于变量都应该使用nonatomic
weak&& strong
weak
- weak型的指针变量仍然可以指向一个对象,但不属于对象的拥有者。
- weak是弱引用,相当于assign,不会造成循环引用
strong
- 强引用,相当于retain.
- 只要引用存在,对象就不能被销毁。这是一种所期望 的行为:当所有(强)引用都去除时,对象才能被收集和释放。
weak和strong的区别有个经典的比喻,小孩与狗。
一个对象类比为一条狗, 释放对象 类比为 狗要跑掉
逻辑:
strong类型的指针就像是栓住的狗,只要你用 绳子拴住狗,那么狗就不会跑掉.
类比 一个对象 new过以后,不会自动的释放
如果有5个人都牵着这一条狗(5条绳子栓一只狗) 类比为 5个strong类型指针指向一个对象.
除非5个绳子都脱落,否则狗是不会跑掉的,类比,5个strong指针都=nil,则该对象释放
weak型指针就像是一个小孩子指着狗喊道:“看,有一只狗在那里”,只要狗一直被拴着,那么小孩子就能看到狗 (weak指针)会一直指向它,
只要狗的绳子脱落,那么狗就会跑掉,不管有多少的小孩在看着它。
只要最后一个strong型指针不再指向对象,那么对象就会被释放,同时所有的weak型指针都将会被清除。
weak&& assign
在ARC环境下,strong相当于retain,weak相当于assign。但是用weak修饰基本类型的时候报红了
因为weak只能修饰对象类型,assign使用于修饰基本类型
copy&& strong
一般情况下可变属性用strong,不可变属性用copy
当源字符串是NSMutableString时,strong属性只是增加了源字符串的引用计数,而copy属性则是对源字符串做了次深拷贝,产生一个新的对象,且copy属性对象指向这个新的对象。另外需要注意的是,这个copy属性对象的类型始终是NSString,而不是NSMutableString,因此其是不可变的。