MST

星途 面试题库

面试题:Objective-C的内存管理机制及ARC原理

描述Objective-C传统的MRC(手动引用计数)内存管理方式,并解释ARC(自动引用计数)是如何工作的。ARC有哪些优点和潜在的问题?在ARC环境下,如何处理循环引用问题?
40.6万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试

MRC(手动引用计数)内存管理方式

在MRC下,开发者需要手动管理对象的内存。每个对象都有一个引用计数(retain count),当对象被创建时,引用计数为1。

  1. retain:发送retain消息会使对象的引用计数加1。例如NSObject *obj = [[NSObject alloc] init]; [obj retain];,这样obj的引用计数变为2。
  2. release:发送release消息会使对象的引用计数减1。例如[obj release];obj的引用计数变为1。当引用计数降为0时,对象会被销毁,其占用的内存会被释放。
  3. autorelease:发送autorelease消息会将对象放入自动释放池(autorelease pool)。当自动释放池被销毁时,池中的所有对象都会收到release消息。例如NSObject *obj = [[[NSObject alloc] init] autorelease];,对象obj会在自动释放池销毁时被释放。

ARC(自动引用计数)工作原理

ARC是由编译器自动管理对象的内存。编译器会在适当的位置自动插入retainreleaseautorelease代码。

  1. 对象生命周期管理:当对象被创建时,ARC会为其分配内存并设置引用计数为1。当对象的引用计数变为0时,ARC会自动释放对象所占用的内存。
  2. 作用域相关:当对象超出其作用域(例如函数结束、局部变量所在块结束),如果没有其他强引用指向该对象,ARC会自动减少其引用计数,可能导致对象被释放。

ARC的优点

  1. 减少内存管理错误:开发者无需手动编写retainrelease代码,大大减少了因忘记释放对象(内存泄漏)或过度释放(野指针)导致的错误。
  2. 提高开发效率:节省了开发者处理内存管理的时间,使开发者可以更专注于业务逻辑。
  3. 性能优化:ARC可以根据对象的生命周期更高效地管理内存,减少不必要的引用计数操作。

ARC的潜在问题

  1. 循环引用:如果两个或多个对象相互强引用,就会形成循环引用,导致对象无法释放。这在ARC下依然存在。
  2. 调试困难:由于内存管理代码由编译器自动插入,当出现内存相关问题时,调试难度可能会增加,因为开发者看不到直接的内存管理代码。

在ARC环境下处理循环引用问题

  1. 使用弱引用(weak reference):对于相互引用的情况,将其中一个引用声明为weak。例如在一个视图控制器(ViewController)和其内部的一个自定义视图(CustomView)相互引用时,在CustomView中对ViewController的引用可以声明为weak
@property (nonatomic, weak) ViewController *viewController;

weak引用不会增加对象的引用计数,从而打破循环引用。 2. 使用无主引用(unowned reference):类似于weak,但unowned引用不会被自动设置为nil,当被引用对象被释放后,unowned引用会变成野指针。适用于确定被引用对象的生命周期至少和引用对象一样长的情况。例如:

@property (nonatomic, unowned) SomeObject *otherObject;