iOS 面试题(四):block 什么时候需要构造循环引用

问题:有没有这样一个需求场景,block 会产生循环引用,但是业务又需要你不能使用 weak self? 如果有,请举一个例子并且解释这种情况下如何解决循环引用问题。

答案:需要不使用 weak self 的场景是:你需要构造一个循环引用,以便保证引用双方都存在。比如你有一个后台的任务,希望任务执行完后,通知另外一个实例。在我们开源的 YTKNetwork 网络库的源码中,就有这样的场景。

在 YTKNetwork 库中,我们的每一个网络请求 API 会持有回调的 block,回调的 block 会持有 self,而如果 self 也持有网络请求 API 的话,我们就构造了一个循环引用。虽然我们构造出了循环引用,但是因为在网络请求结束时,网络请求 API 会主动释放对 block 的持有,因此,整个循环链条被解开,循环引用就被打破了,所以不会有内存泄漏问题。代码其实很简单,如下所示:

//  YTKBaseRequest.m
- (void)clearCompletionBlock {
   // nil out to break the retain cycle.
   self.successCompletionBlock = nil;
   self.failureCompletionBlock = nil;
}

总结来说,解决循环引用问题主要有两个办法:

第一个办法是「事前避免」,我们在会产生循环引用的地方使用 weak 弱引用,以避免产生循环引用。

第二个办法是「事后补救」,我们明确知道会存在循环引用,但是我们在合理的位置主动断开环中的一个引用,使得对象得以回收。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • iOS网络架构讨论梳理整理中。。。 其实如果没有APIManager这一层是没法使用delegate的,毕竟多个单...
    yhtang阅读 5,316评论 1 23
  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,241评论 30 472
  • http://blog.csdn.net/david21984/article/details/57451917 ...
    紫色冰雨阅读 596评论 0 0
  • 转载自:iOS 面试题 28、找出两个 UIView 的最近的公共 View,如果不存在,则输出 nil 。 分析...
    John_LS阅读 703评论 0 1
  • 6月,濛濛的雨,碎碎的花,时时露出的阳光笑脸,携手去旷野,山青水秀,放声高歌,尽情畅饮,欢快舞蹈,唱出自由,舞出自...
    欧阳玉倩阅读 277评论 0 0