在 Objective-C 中,@property
的修饰符有几种不同的类型,每个修饰符决定了属性的内存管理方式、读写权限、以及线程安全性等。以下是常见的修饰符及其区别的表格:
修饰符 | 描述 | 使用场景 |
---|---|---|
strong |
保持对对象的强引用,确保该对象在此属性存在期间不会被释放。 | 适用于引用需要保持对象存在的属性,例如视图、数据模型等。 |
weak |
对对象的弱引用,不会保留对象实例,若对象被释放时,属性会自动设为 nil 。 |
适用于防止循环引用的场景,例如 delegate 或 parent-child 结构的子级对父级的引用。 |
assign |
直接赋值,不进行引用计数管理,适用于基本数据类型(如 int 、float 、BOOL )。 |
适用于非对象类型,或者不需要强引用的属性。 |
copy |
赋值时对对象进行拷贝,生成一个新的副本。适用于 NSString 、NSArray 等类型,确保外部对对象的修改不会影响属性值。 |
适用于不可变类对象的存储,特别是 NSString 等类型,防止原始值改变时的意外影响。 |
nonatomic |
非原子性访问,不加锁,访问速度快但不保证线程安全。 | 多用于无并发访问需求的场景,如 UI 层的属性。 |
atomic (默认) |
原子性访问,加锁以保证线程安全,但性能稍低。 | 多用于并发访问需求的场景,但一般不推荐使用,性能开销大。 |
readonly |
只读属性,只生成 getter 方法。 |
适用于只允许外部读取而不允许修改的属性。 |
readwrite (默认) |
读写属性,生成 getter 和 setter 方法。 |
适用于属性既需要读也需要写的场景。 |
nullable |
表示属性可以为空,通常用于接口设计中,表明该属性可能为 nil 。 |
适用于可能为空的属性,用于增强代码的可读性和安全性。 |
nonnull |
表示属性不能为空,强制要求在初始化时提供值。 | 适用于必须有值的属性,防止 nil 导致的异常。 |
示例用法
objc
复制代码
@property (nonatomic, strong) NSString *name; // 保持对象存在,适合 NSString 等 @property (nonatomic, weak) id<Delegate> delegate; // 弱引用,避免循环引用 @property (nonatomic, assign) int age; // 基本数据类型 @property (nonatomic, copy) NSArray *items; // 复制不可变集合,防止意外修改 @property (nonatomic, readonly) NSString *info; // 只读属性,不生成 setter 方法 @property (nonatomic, nullable) NSString *nickname; // 属性允许为 nil