面试题答案
一键面试属性修饰符作用
- nonatomic与atomic:
- nonatomic:非原子性访问,访问速度快,不会对属性的访问加锁。在多线程环境下,可能会出现数据竞争问题,但在单线程或对线程安全要求不高的场景下,能提高性能。
- atomic:原子性访问,默认修饰符。为属性的访问加锁,确保同一时间只有一个线程能访问属性,线程安全,但会有性能开销。
- strong与weak:
- strong:强引用,持有对象,使对象的引用计数加1。当一个对象被多个强引用指向时,对象不会被释放,直到所有强引用都被销毁。
- weak:弱引用,不持有对象,不会使对象的引用计数增加。当对象的强引用计数变为0被释放后,指向该对象的所有弱引用会自动被设置为
nil
,避免野指针。
- copy:
- copy:创建一个新的对象副本,新对象的引用计数为1。对于不可变对象(如
NSString
、NSArray
、NSDictionary
),copy
操作返回指向自身的指针;对于可变对象,会创建一个新的不可变副本。常用于防止对象在外部被修改。
- copy:创建一个新的对象副本,新对象的引用计数为1。对于不可变对象(如
业务场景举例及修饰符选择
- 单线程场景:
- 如果属性是简单的数据类型,并且对线程安全要求不高,如一个只在主线程使用的
NSString
属性,可以使用nonatomic
、strong
修饰,以提高访问性能。
@interface MyViewController : UIViewController @property (nonatomic, strong) NSString *titleText; @end
- 如果属性是简单的数据类型,并且对线程安全要求不高,如一个只在主线程使用的
- 多线程场景:
- 若属性是经常在多线程中读写的对象,如一个共享的数据模型,可以使用
atomic
、strong
来确保线程安全。
@interface DataModel : NSObject @property (atomic, strong) NSString *sharedData; @end
- 若属性是经常在多线程中读写的对象,如一个共享的数据模型,可以使用
- 防止对象被修改场景:
- 当需要确保属性值不被外部改变时,对于
NSString
等对象,使用copy
修饰。例如,一个表示用户名的属性,不希望外部修改其值。
@interface User : NSObject @property (nonatomic, copy) NSString *userName; @end
- 当需要确保属性值不被外部改变时,对于
- 避免循环引用场景:
- 在存在父子视图关系或委托关系时,为避免循环引用,通常将子视图或委托属性设置为
weak
。如在视图控制器中,视图控制器持有子视图的强引用,子视图的代理属性设置为weak
。
@interface ChildView : UIView @property (nonatomic, weak) id<ChildViewDelegate> delegate; @end
@interface ParentViewController : UIViewController @property (nonatomic, strong) ChildView *childView; @end
- 在存在父子视图关系或委托关系时,为避免循环引用,通常将子视图或委托属性设置为