zoukankan      html  css  js  c++  java
  • 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 弱引用,以避免产生循环引用。
    • 第二个办法是「事后补救」,我们明确知道会存在循环引用,但是我们在合理的位置主动断开环中的一个引用,使得对象得以回收。

    思考题

    下期的问题是:weak 变量在引用计数为 0 时,会被自动设置成 nil,这个特性是如何实现的?

  • 相关阅读:
    zoj2132-The Most Frequent Number
    ant-design getFieldDecorator 无法获取自定义组件的值
    ant-design-pro Login 组件 实现 rules 验证
    js 终止 forEach 循环
    js 终止 for 循环
    vue打包后出现一些map文件的解决方法
    ant font 本地化
    react 设置代理(proxy) 实现跨域请求
    ES6 async 与 await 实战
    {...formItemLayout} 标签布局
  • 原文地址:https://www.cnblogs.com/weiboyuan/p/6143530.html
Copyright © 2011-2022 走看看