面试题答案
一键面试可能遇到的内存管理问题
- 循环引用:两个或多个视图控制器相互持有对方创建的对象,导致对象之间形成强引用环,对象无法被释放,造成内存泄漏。例如,视图控制器A持有对象O,对象O又持有视图控制器B,而视图控制器B也持有对象O,这样就形成了循环引用。
- 过早释放:如果传递对象时没有正确管理引用,接收对象的视图控制器可能在仍需要该对象时,对象已被释放,导致程序崩溃,出现悬空指针引用问题。
解决方法
- 避免循环引用:
- 使用弱引用(Weak Reference):在属性声明时使用
weak
关键字。例如,若视图控制器B持有对象O,而对象O持有视图控制器B,可以将视图控制器B对对象O的引用设为weak
。
@property (nonatomic, weak) MyObject *myObject;
weak var myObject: MyObject?
- 使用无主引用(Unowned Reference):当确定对象之间的生命周期不会产生循环引用,但其中一个对象的生命周期依赖于另一个对象时,可以使用无主引用。例如,在Swift中:
在Objective - C中,可以使用unowned let myObject: MyObject
__unsafe_unretained
关键字,但要注意它可能导致悬空指针,使用时需谨慎。 - 使用弱引用(Weak Reference):在属性声明时使用
- 确保正确的对象生命周期:
- 强引用(Strong Reference):在传递对象时,接收对象的视图控制器需要对对象保持强引用,确保在其使用期间对象不会被释放。例如,在属性声明时使用
strong
关键字(Objective - C)或默认的强引用(Swift)。
@property (nonatomic, strong) MyObject *myObject;
var myObject: MyObject
- 自动释放池(Autorelease Pool):在iOS开发中,自动释放池会自动释放其包含的对象。当对象传递完成且不再被需要时,若没有其他强引用,对象会在合适的时机被自动释放。在编写代码时,若有大量临时对象创建,可以手动创建自动释放池块来及时释放内存。
@autoreleasepool { // 创建和使用临时对象 }
autoreleasepool { // 创建和使用临时对象 }
- ARC(自动引用计数):iOS 5.0引入的ARC机制会自动管理对象的内存。开发者无需手动调用
retain
、release
和autorelease
方法,ARC会根据对象的引用计数自动释放不再被引用的对象。但开发者仍需注意避免循环引用等问题,确保对象生命周期管理正确。
- 强引用(Strong Reference):在传递对象时,接收对象的视图控制器需要对对象保持强引用,确保在其使用期间对象不会被释放。例如,在属性声明时使用