「这是我参与11月更文挑战的第20天,活动详情查看:2021最后一次更文挑战」。
@property 有两个的作用:一是自动生成私有属性(一般是下划线+属性名),而是自动生成 getter
和 setter
方法。
声明属性时,紧跟在 @property 之后的属性修饰符则描述了自动生成 getter
和 setter
方法的规则。
根据MRC和ARC划分属性修饰符的使用范围:
MRC:nonatomic,atomic,retain,assign,copy,readwrite,readonly
ARC:nonatomic,atomic,strong,weak,assign,copy,readwrite,readonly
-
nonatomic
-
nonatomic 表示非原子属性
-
并发访问性能高,但是访问不安全
- 它直接访问内存中的地址,不关心其他线程是否在改变这个值,并且中间没有死锁保护;所以可能拿不到完整的值
-
-
-
atomic
-
atomic 表示原子属性
-
系统生成的 getter/setter 会保证 get、set 操作的完整性,不受其他线程影响
- 系统生成的 getter/setter 方法中,使用了 @synchronized(self)
- 如果一个线程正在执行 getter/setter,其他线程就得等待
-
如果有另一个线程同时在调 [property release],那可能就会crash,因为 release 不受 getter/setter 操作的限制。
-
也就是说,atomic 修饰的属性只能说是读/写安全的,但并不是线程安全的
- 因为别的线程还能进行读写之外的其他操作。
- 线程安全需要开发者自己来保证。
-
-
-
系统默认的属性是 atomic
-
-
strong
-
strong 表示对对象的强引用
- 强引用时,引用计数会 +1
- 给 strong 属性赋值时,setter 方法中会先 release 旧值再 retain 新值并赋值
- 两个对象之间相互强引用会造成循环引用,内存泄漏
-
-
weak
-
weak 表示对象的弱引用
-
弱引用时,不会使传入的对象计数+1
-
被其修饰的对象随时可能被系统销毁回收
-
当该对象的引用计数为 0,则会被回收,对象被释放以后,weak 指针会被自动设置为 nil
在OC的运行时环境中,维护了一种 weak 表(哈希表)
这张哈希表用对象的首地址作为 key,用 weak 指针自身的地址组成的数组作为 value
当对象被释放后,通过这个对象的起始地址来找到所有指向它的 weak 指针,并将它们指向nil
-
-
weak 多用于避免循环引用
-
-
-
assign
-
assign 主要用于修饰基本数据类型
- 包括OC基本数据类型(NSInteger,CGFloat)和C数据类型(int, float, double, char)
-
基本数据类型存储在栈中,内存不用程序员管理。
-
assign 也可以修饰对象,但是当对象被释放后,指针依然指向之前的内存地址。\
-
此时,访问被释放的地址就会 crash
-
这个已经被释放了的对象被称为 僵尸对象
-
-
assign 在 MRC 和 ARC 下都可以使用
-