属性
@property
尽管可以使用 obj->arr 的形式去强制读取对象的成员变量,但是良好的编程形式是对外界提供成员变量的读写接口。**@property** 关键字提供了外界对成员变量的访问接口,其本质是自动为某一个属性生成 set 和 get 方法。
根据不同的需要,可以添加 readonly(只读,相当于只添加 get 不添加 set 方法)或者 readwrite(读写,如果不添加则为默认);
还有三种赋值方式可选 :assign(直接赋值,通常用于基本类型),retain(释放旧值,增加新的 retaincount),copy(常用于字符串,生成一个新的拷贝).
property 的属性特性只对 setter 方法有效,对 getter 方法无效
格式:
@property (原子性©,内存管理©,读写性©) NSString *string;
属性特征
原子性
atomic(默认):原子性
atomic 意为操作是原子的,意味着只有一个线程访问实例变量。atomic 是线程安全的,至少在当前的存取器上是安全的。它是一个默认的特性,但是很少使用,因为比较影响效率,这跟 ARM 平台和内部锁机制有关。
nonatomic: 非原子性
nonatomic 跟 atomic 刚好相反。表示非原子的,可以被多个线程访问。它的效率比 atomic 快。但不能保证在多线程环境下的安全性,在单线程和明确只有一个线程访问的情况下广泛使用。
内存管理
assign(默认):对象之外的类型使用,一般用来修饰基础数据类型);
1⃣️ 用于修饰值类型(基本数据类型),如:int,float,double,CGFloat,NSInteger 等。还包括不存在所有权关系的对象,如:delegate。
相对于 assign ,我们一般使用 weak 来修饰 delegate,会更加安全。
2⃣️ assign 修饰的属性不牵涉内存管理,不会被引用计数器管理。
retain:保留对象;(所有的对象,都使用 retain)
在
setter
方法中,需要对传入的对象进行引用计数加 1 的操作。
简单来说,就是对传入的对象拥有所有权,只要对该对象拥有所有权,该对象就不会被释放。copy:拷贝对象;NSString/NSArray 的对象都使用 copy 属性;
strong:强引用
strong 是在 IOS 引入 ARC 的时候引入的关键字,是 retain 的一个可选的替代。表示实例变量对传入的对象要有所有权关系,即强引用。strong 跟 retain 的意思相同并产生相同的代码,但是语意上更好更能体现对象的关系。
weak:弱引用,一般用来修饰对象。
针对对象类型,在 setter 方法中,不会对传入的对象执行引用计数器 + 1 的操作。也就是对传入的对象没有所有权,是弱引用。另外当传入的对象引用计数器为 0,也就是被释放后,用 weak 声明的实例变量会指向 nil,即空对象。
unsafe_unretained:
1⃣️ 从字面上来看,我们可以拆分成两部分来理解,unretained 和 retain 相反,也就是和 strong 相反,因此等同于 weak,其实也是用在 iOS5 之前替代 weak 使用的。
2⃣️ unsafe,不安全的,如上所述等同于 weak 的话那应该是安全的,这里不安全的是指当传入的对象被释放后,使用 unsafe_unretained 修饰的变量是不知道的,也不会像 weak 一样指向 nil,所以此时访问可能会引起 crash。因此,总结来说 unsafe_unretained 作用是等同于 weak,但是是不安全的。
读写性
readwrite(默认):
readwrite
是默认值,表示该属性同时拥有setter
和getter
。readonly:只读
readonly
表示只有getter
没有setter
。
参考文章
- 我所理解的内存管理:4、property 相关 @杨淳引
- 理解 @property 使用的关键字 @MrLeoZou
- Objective-C 中的 @property @程序员说
- Objective-C 内存管理 —— 你需要知道的一切
- 理解 iOS 的内存管理 @唐巧