51mee - AI智能招聘平台Logo
模拟面试题目大全招聘中心会员专区

在iOS开发中,你如何处理循环引用(循环引用问题)?请举例说明在什么场景下容易发生循环引用,以及如何避免?

八方职达 | 广州创思信息技术有限公司IOS开发难度:中等

答案

1) 【一句话结论】在iOS开发中,处理循环引用的核心是通过弱引用(weak)或无主引用(unowned)打破对象间的强引用循环,避免内存泄漏,具体场景如视图控制器与视图、模型对象间的引用,需根据对象是否可能为nil选择合适引用类型。

2) 【原理/概念讲解】循环引用是指两个或多个对象互相持有对方,形成强引用(strong)循环,导致系统无法通过引用计数为0释放这些对象,从而造成内存泄漏。类比:两个朋友A和B,A说“我等你吃饭”,B说“我等你吃饭”,谁都不先放话,结果两人都等不到对方,内存(吃饭机会)一直存在。在iOS中,对象通过强引用互相持有,引用计数增加,当所有强引用消失时,引用计数才为0,循环中每个对象的引用计数永远不会为0,因此无法释放。

3) 【对比与适用场景】

引用类型定义特性使用场景注意点
weak弱引用,不增加引用计数对象可能为nil,适用于可能被释放的对象当一个对象可能被释放(如视图控制器在视图消失时被释放),持有它的对象用weak必须在对象被释放前设置,否则可能访问nil
unowned无主引用,不增加引用计数对象不会为nil,适用于对象生命周期与持有者一致当一个对象的生命周期与持有者完全一致,不会在持有者存在时被释放如果对象提前释放,访问会导致野指针(crash)

4) 【示例】
假设有一个网络请求的代理对象(如NSURLSessionDelegate),视图控制器持有代理,代理持有视图控制器,形成循环。伪代码:

  • ViewController.h:
    @interface ViewController : UIViewController <NSURLSessionDelegate>  
    @property (nonatomic, weak) NSURLSessionDelegate *delegate; // 视图控制器持有代理(weak)  
    
  • URLSessionDelegate.h:
    @interface MyDelegate : NSObject <NSURLSessionDelegate>  
    @property (nonatomic, strong) ViewController *viewController; // 代理持有视图控制器(strong)  
    

当视图控制器销毁时,代理还持有它,导致循环。解决:视图控制器用weak持有代理,代理用unowned持有视图控制器(假设视图控制器不会在代理存在时被释放)。

5) 【面试口播版答案】
在iOS开发中,循环引用是指两个或多个对象互相持有,导致内存无法释放。常见场景比如视图控制器与它管理的视图模型、或者网络请求的代理对象。处理方法是使用弱引用(weak)或无主引用(unowned)打破循环。比如,视图控制器持有代理用weak,代理持有视图控制器用unowned(如果视图控制器不会在代理存在时被释放)。核心是避免强引用循环,确保当一个对象被释放时,另一个对象不再持有它。

6) 【追问清单】

  • 问:weak和unowned的区别?答:weak可能为nil,适用于可能被释放的对象;unowned不会为nil,适用于对象生命周期与持有者一致的场景。
  • 问:block中如何避免循环引用?答:在block中设置self为weak(如__weak __typeof(self)weakSelf = self;),或者使用__block(需注意线程安全)。
  • 问:循环引用在多线程中是否会有问题?答:多线程中引用计数规则不变,但需注意线程安全,比如使用GCD的队列或锁,避免并发访问导致问题。
  • 问:在MVC架构中,循环引用常见吗?答:常见,比如控制器持有模型,模型持有控制器,需用weak或unowned替换强引用。
  • 问:如果对象有多个持有者,如何避免循环?答:检查所有可能的强引用路径,用weak或unowned替换,确保至少有一个持有者不增加引用计数。

7) 【常见坑/雷区】

  • 用weak代替unowned导致野指针:如果对象生命周期不一致(如代理先释放,视图控制器后释放),用weak可能访问nil,但用unowned不会,需根据实际场景选择。
  • 忘记在block中设置weak:block中self是强引用,导致循环引用,需在block内将self设为weak。
  • 循环引用在子类中:子类可能继承父类的强引用,导致新的循环,需检查子类中的所有引用。
  • 内存泄漏检测工具:比如Instruments的Leaks工具,能检测循环引用,但需正确配置,避免误报。
  • 多个弱引用:如果多个对象用weak持有同一个对象,不会形成循环,但需注意对象是否被释放,否则可能访问nil。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1