iOS属性的修饰符包括三个方面
读写权限修饰符:
线程安全:
内存管理:
内存管理的本质是什么?
因为对象和其他数据类型在系统中的存储空间不一样,其它局部变量主要存放于栈中,而对象存储于堆中
,当代码块结束时这个代码块中涉及的所有局部变量会被回收,指向对象的指针也被回收,此时对象已经没有指针指向,但依然存在于内存中,造成内存泄露。
strong
属于强引用表示指向并拥有该对象,其修饰的对象引用计数会增加1
。该对象只要引用计数不为0则不会被销毁。如果强行设置为nil可以销毁它。
retain
retain和strong效果一样,引用计数加1,ARC下已经不再使用,用strong代替
。
weak
属于弱引用表示指向但不拥有该对象,其修饰的对象的引用计数不会增加
,ARC模式使用,相当于assign,对象废弃可以把对应指针变量置为nil的状态,只可以修饰对象,不可以修饰基本数据类型
。在ARC中有可能会出现循环引用的情况,往往通过其中一端使用weak来解决, 比如delagate代理属性,自身已经对它有过一次强应用,没有必要再强引用一次,这个时候也会使用weak。
assign
主要用于修饰基本数据类型
,例如int,NSInteger,CGFloat等,这些数值主要存在于栈上
。不涉及内存管理
,内存技术不改变,如果修饰对象类型的话会出现野指针或者EXC_BAD_ACCESS错误
。
Copy
建立一个索引计数为1的对象,在赋值的时使用传入值的一份拷贝,适用于NSString和block。block 使用 copy 是从 MRC 遗留下来的“传统”,在 MRC 中方法内部的 block 是在栈区的,使用 copy 可以把它放到堆区
。在 ARC 中对于 block 使用 copy 还是 strong 效果是一样的,如果不写 copy ,这样在作用域外调用该block程序就会崩溃
,该类的调用者有可能会忘记或者根本不知道编译器会自动对 block 进行了 copy 操作,他们有可能会在调用之前自行拷贝属性值。
只创建一个新的指针,指向原指针指向的内存
创建一个新的指针,并开辟新的内存空间,内容拷贝自原指针指向的内存,并指向它
atomic(默认属性)
当前进程进行到一半,其他线程来访问当前线程,可以保证先执行完毕当前线程。只是保证setter/getter完整
,不是线程安全。atomic修饰的设值、取值方法使用了自旋锁
,确保线程同步
。虽然设值、取值方法是原子操作,但不代表是线程安全
。
nonatomic(非默认属性)
两个线程同时访问同一个属性将会导致无法预计的结果。优点是程序运行速度快
。