面试题答案
一键面试底层原理优化
- 减少动态关联操作:尽量在初始化阶段就完成对象关联,避免在高并发时频繁调用
objc_setAssociatedObject
等动态关联函数。因为动态关联操作涉及到哈希表查找、内存分配等开销,频繁操作会降低性能。例如,可以在对象初始化方法init
中完成关联设置。 - 优化关联存储结构:了解关联对象在底层是通过
AssociationsManager
、AssociationsHashMap
以及ObjectAssociationMap
等数据结构存储的。对于大量对象的关联,可以考虑根据业务特点对关联对象进行分组管理,减少哈希冲突,提高查找效率。比如,按照对象类型或者业务模块对关联对象进行分类存储。
内存管理优化
- 及时释放关联对象:确保在对象销毁时,关联对象也能正确释放。使用
OBJC_ASSOCIATION_RETAIN_NONATOMIC
、OBJC_ASSOCIATION_ASSIGN
等合适的关联策略。对于OBJC_ASSOCIATION_RETAIN_NONATOMIC
策略,要注意循环引用问题,可通过弱引用(OBJC_ASSOCIATION_ASSIGN
)或者__weak
修饰符来打破循环。例如,在一个视图控制器持有一个关联的自定义数据对象时,如果担心循环引用,可将关联策略设置为OBJC_ASSOCIATION_ASSIGN
。 - 避免不必要的内存分配:在属性注入时,尽量复用已有的对象,而不是每次都创建新对象。比如,对于一些常量性质的属性,可以使用单例模式提供的对象进行注入,减少内存碎片的产生。
锁机制优化
- 使用读写锁:如果属性注入和关联对象操作存在多读少写的情况,可以使用读写锁(如
pthread_rwlock
)。读操作时允许多个线程同时进行,写操作时则独占锁,这样可以提高并发性能。例如,在一个多线程读取关联对象属性,但偶尔更新属性值的场景中,读写锁能有效提升效率。 - 细粒度锁:不要对整个对象或者模块使用一把大锁,而是根据操作的具体部分,使用细粒度锁。比如,对于对象不同属性的注入操作,可以为每个属性或者相关属性组设置单独的锁,这样不同线程可以同时操作不同属性,减少锁竞争。但要注意锁的数量不宜过多,否则会增加锁管理的开销。