面试题答案
一键面试常见修饰符
- 原子性(atomicity)
- atomic:默认修饰符,为属性的存取方法生成线程安全的代码,保证同一时间只有一个线程能访问该属性。在多线程环境下,通过锁机制确保属性访问的完整性。
- nonatomic:不提供线程安全保障,在多线程环境下,可能出现多个线程同时访问属性的情况,会导致数据竞争和不一致。但由于没有锁的开销,其访问速度比
atomic
快。
- 读写权限(read - writeability)
- readwrite:默认修饰符,同时生成属性的
getter
和setter
方法,允许读取和写入属性值。 - readonly:只生成
getter
方法,属性只能读取,不能写入,常用于一些只需要对外提供读取功能的属性。
- readwrite:默认修饰符,同时生成属性的
- 内存管理(memory management)
- assign:用于基本数据类型(如
int
、float
、double
等),简单赋值,不涉及引用计数的管理。当对象被释放时,不会自动处理与之关联的属性。 - retain:用于对象类型,会增加对象的引用计数。当设置属性值时,先释放旧值(如果有),再对新值进行
retain
操作。在ARC环境下已不推荐使用。 - strong:ARC环境下等同于
retain
,表示对对象的强引用,持有对象,使其引用计数加1。当强引用计数变为0时,对象被释放。 - weak:用于对象类型,建立弱引用,不会增加对象的引用计数。当对象被释放时,指向该对象的弱引用会自动被设置为
nil
,从而避免野指针。常用于解决循环引用问题,如视图控制器之间的父子关系。 - unsafe_unretained:类似于
weak
,但当对象被释放时,指向它的指针不会被自动设为nil
,可能导致野指针,一般较少使用。
- assign:用于基本数据类型(如
- 方法名(method naming)
- getter = customGetter:指定自定义的
getter
方法名。例如,@property (nonatomic, getter = isFinished) BOOL finished;
,此时访问属性使用isFinished
方法。 - setter = customSetter::指定自定义的
setter
方法名。例如,@property (nonatomic, setter = setTotalCount:) NSInteger totalCount;
,设置属性值时使用setTotalCount:
方法。
- getter = customGetter:指定自定义的
nonatomic在多线程环境下对属性访问的影响
在多线程环境中,nonatomic
修饰的属性由于没有线程安全保护机制,多个线程可能同时访问和修改该属性。这可能导致数据竞争问题,例如一个线程正在读取属性值,另一个线程同时修改了该值,使得读取到的数据不一致。此外,如果属性是对象类型且涉及复杂的操作(如对NSMutableArray
进行添加和删除元素操作),nonatomic
可能导致数据损坏。然而,由于nonatomic
没有锁的开销,在单线程环境或对线程安全要求不高的场景下,能提高属性访问的性能。