问题

有没有这样一个需求场景,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,这个特性是如何实现的?

iOS 面试题(四):block 什么时候需要构造循环引用 --转自唐巧的更多相关文章

  1. iOS 面试题(一):寻找最近公共 View --转自唐巧

    题目:找出两个 UIView 的最近的公共 View,如果不存在,则输出 nil . 分析:这其实是数据结构里面的找最近公共祖先的问题. 一个 UIViewController 中的所有 view 之 ...

  2. block本质探寻八之循环引用

    说明:阅读本文,请参照之前的block文章加以理解: 一.循环引用的本质 //代码——ARC环境 void test1() { Person *per = [[Person alloc] init]; ...

  3. block中self会造成循环引用问题

    将代码块中的 self换成unsafeSelf __unsafe_unretained 与 __weak 99%相同 __weak 当对象释放之后 会自动设置为nil 而__unsafe_unreta ...

  4. iOS 面试题(二):什么时候在 block 中不需要使用 weakSelf --转自唐巧

    问题 我们知道,在使用 block 的时候,为了避免产生循环引用,通常需要使用 weakSelf 与 strongSelf,写下面这样的代码: __weak typeof(self) weakSelf ...

  5. IOS 浅谈闭包block的使用

    前言:对于ios初学者,block通常用于逆向传值,遍历等,会使用,但是可能心虚,会感觉block很神秘,那么下面就一起来揭开它的面纱吧. ps: 下面重点讲叙了闭包的概念,常用的语法,以及访问变量, ...

  6. iOS Block循环引用

    在介绍block循环引用前我们先了解一下typeof. typeof是什么??? typeof 是一个一元运算,放在一个运算数之前,运算数可以是任意类型. 它返回值是一个字符串,该字符串说明运算数的类 ...

  7. IOS block 循环引用的解决

    在介绍block循环引用前我们先了解一下typeof. typeof是什么??? typeof 是一个一元运算,放在一个运算数之前,运算数可以是任意类型. 它返回值是一个字符串,该字符串说明运算数的类 ...

  8. iOS 面试全方位剖析 -- Block篇

    1.Block的本意 block本质上也是一个OC对象,它内部也有个isa指针, block是封装了函数调用以及函数调用环境的OC对象, block是封装函数及其上下文的OC对象 2.block截获变 ...

  9. block(六)循环引用-b

    在ARC与非ARC环境下对block使用不当都会引起循环引用问题,一般表现为,某个类将block作为自己的属性变量,然后该类在block的方法体里面又使用了该类本身,简单说就是self.theBloc ...

随机推荐

  1. TFS二次开发系列:一、TFS体系结构和概念

    TFS是Team Fundation Server的简称,是微软VSTS的一部分,它是Microsoft应用程序生命周期管理(ALM)工具的核心协作平台,简单的说它是管理和开发软件项目的整个生命周期的 ...

  2. mysql远程连接问题

    问题:在服务器里面新安装一个MYSQL数据库,结果在远程电脑连接不上,并提示“服务器连接错误Host 'XXX' is not allowed to connect to this MySQL ser ...

  3. Linux下安装JDK多种方式

    一.环境说明: 操作系统:Linux xx- -.el6.x86_64 # SMP Thu Jul :: UTC x86_64 x86_64 x86_64 GNU/Linux jdk版本:java-- ...

  4. MIS系统开发利器,实施、维护人员自定义报表的福音,AgileEAS.NET SOA平台动态报表指南

    一.前言 AgileEAS.NET SOA 中间件平台是一款基于基于敏捷并行开发思想和Microsoft .Net构件(组件)开发技术而构建的一个快速开发应用平台.用于帮助中小型软件企业建立一条适合市 ...

  5. java基础(四)

    一.面向对象的三个基本特征: 1.封装,将对象的实现细节隐藏起来,并通过公共接口暴露相关功能: 2.继承,代码复用的表现,当子类继承父类后,子类作为一种特殊的父类,直接获得父类的属性和方法: 3.多态 ...

  6. JAVE not work in linux

    1, it will print out exception, but still can convert the audio 2, it works in windows not linux, ne ...

  7. HTML: vertical algin Big/small div in same row (bootstrap)

    Reference: http://stackoverflow.com/questions/20547819/vertical-align-with-bootstrap-3?answertab=vot ...

  8. marquee-:模拟弹幕

              marquee:基本已被弃用!!1 可以模拟弹幕效果           1.方向:direction             up  right   left  down     ...

  9. ZeroMQ接口函数之 :zmq_msg_send – 从一个socket发送一个消息帧

    ZeroMQ 官方地址 :http://api.zeromq.org/4-0:zmq_msg_send zmq_msg_send(3) ØMQ Manual - ØMQ/3.2.5 Name zmq_ ...

  10. [LintCode] Single Number 单独的数字

    Given 2*n + 1 numbers, every numbers occurs twice except one, find it. Have you met this question in ...