原文地址:http://www.cnblogs.com/lujianwenance/p/5910490.html
  Block在实际的开发中非常的常用,事件回调、传值、封装成代码块调用等等。很多人都对block有一个直观的印象,就是需要weak对象,打破当前的引用循环。引用循环相信大家都不陌生,比如A引用B,B引用了A;或者A->B , B->C,C->A;中间的引用如果不能断开就会引用循环,造成对象没办法释放导致内存泄露。所以很多人在使用block时都很小心或者说不管有没有引用循环都使用weak。下面分析几种常用的情况:
     1、局部block
          局部的block块,一般是为了同一段代码复用或者清晰代码逻辑使用的,一段代码多次在这个方法或者函数中使用,或者这段代码是不能拆分的,它们是一个整体。当然,不能排除有些人就是为了装B......。如下图:
          
          局部的block持有了self,而self并没有持有block,所以当block代码块执行完之后就会释放自己持有的self,即self的RC计数器-1,这时不会造成引用循环。还有一个类似的场景就是使用Masonry添加约束时,同样不会造成引用循环。
     2、被属性持有的block
          被持有的block中使用self是很典型的引用循环。当block执行完之后,由于block还有人持有,不能被释放,所以block所持有的对象也不能被释放,这样就导致了block->self,self - >block
,如下图:

3、网络请求回调的block

          由于大部分开发者是直接使用的AFNetworking或者其他的第三方的网络请求,基本上都是使用的block,所以这种情况应该是使用block最多情况。在AFNetworking3.0之后,成功和失败的block不会被另外持有,所以很局部的block类似,block执行结束之后,就会释放持有的self。
在AFNetworking3.0之前,如果使用的是NSURLConnection,成功和失败的回调是在NSOperation的completionBlock中被调用的,所以需要被持有,所以AFNetworking是这样处理的,如下图:
          在请求结束之后断开对block的持有,block被释放的同时也会释放成功和失败的回调。避免了引用循环。
          所以在使用afnetworking网络请求中的block不需要使用weak,但是我们大部分的时间里还是会使用,后面会简单的分析我的理解。
          
          从上图中的得到的结果可以验证我们上面的描述,所以合适使用weak对象,需要判断是否导致了引用循环,最后再举一个常见的场景,一个声明成属性的自定义view,包括了一个回调的actionBlock,比如说是点击回调,在这个block中需要操作这个view自己(比如说removeFromSuperView),这时就引起了循环,self->view->block->self,就算block执行完,block也没办法释放,因为这个view还在。这时就需要打破循环。
          最后说一下,为什么大部分的网络请求还是使用的weakSelf,我的理解为,大部分的网络请求回来的数据是依赖于当前的ViewController的,如果当前ViewController没有了,网络请求拿到的数据也就没有意义了,所以使用weak可以很好的处理这种情况,当当前的VC被释放了(pop或者dissmiss等等),就不需要在执行了。然而如果这不是一个ViewController,而是一个类似于Manager的类,比如说做的操作是,将请求回来的数据写到本地(或者别的希望不管什么情况下都能被执行完的操作),这时使用self,能保证block被执行完,然后这个manager释放也就无所谓了。总结一下来说,就是使用self,即strong 类型的对象,可以延迟持有者的释放,但是并不会引起引用循环。
          所以不是在block中使用的对象都是weak的,需要根据当前的需求来判断到底怎样使用,最近工作时间改成了996,累啊,希望下个月能多分享一些内容,希望大家都能有所收获,还是那句话,如果文中有不对的地方,望指正,谢谢。

Block中的引用循环的更多相关文章

  1. 转:Block原理及引用循环问题

    2010年WWDC发布iOS4时Apple对Objective-C进行了一次重要的升级:支持Block.说到底这东西就是闭包,其他高级语音例如Java和C++已有支持,第一次使用Block感觉满简单好 ...

  2. block中如何避免循环引用

    使用 weak–strong dance 技术 block 可以直接引用 self,但是要非常小心地在 block 中引用 self.因为在 block 引用 self,可能会导致循环引用.如下例所示 ...

  3. block使用小结、在arc中使用block、如何防止循环引用

    引言 使用block已经有一段时间了,感觉自己了解的还行,但是几天前看到CocoaChina上一个关于block的小测试主题: [小测试]你真的知道blocks在Objective-C中是怎么工作的吗 ...

  4. Block的引用循环问题 (ARC & non-ARC)

    2010年WWDC发布iOS4时Apple对Objective-C进行了一次重要的升级:支持Block.说到底这东西就是闭包,其他高级语音例如Java和C++已有支持,第一次使用Block感觉满简单好 ...

  5. iOS - Block产生Memory Leaks循环引用导致的内存泄漏以及解决方案

    在ARC(自动引用技术)前,Objective-c都是手动来分配释放 释放 计数内存,其过程非常复杂. ARC技术推出后,貌似世界和平了很多,但是其实ARC并不等同于Java或者C#中的垃圾回收,AR ...

  6. ios 使用block中使用self可能产生的循环引用

    在block中调用 self,那么就会引起循环引用问题,那么这是为什么呢? 为什么self会对block进行强引用呢???? 这里推荐一篇关于block的专业文章,http://blog.csdn.n ...

  7. Block的使用及循环引用的解决

    Block是一个很好用的东西,这篇文章主要来介绍:1.什么是Block?2.Block的使用?3.Block的循环引用问题及解决. 1.什么是Block? 说这个问题之前,我先来说一下闭包(Closu ...

  8. iOS开发笔记15:地图坐标转换那些事、block引用循环/weak–strong dance、UICollectionviewLayout及瀑布流、图层混合

    1.地图坐标转换那些事 (1)投影坐标系与地理坐标系 地理坐标系使用三维球面来定义地球上的位置,单位即经纬度.但经纬度无法精确测量距离戒面积,也难以在平面地图戒计算机屏幕上显示数据.通过投影的方式可以 ...

  9. 讲述Sagit.Framework解决:双向引用导致的IOS内存泄漏(下)- block中任性用self

    前言: 在处理完框架内存泄漏的问题后,见上篇:讲述Sagit.Framework解决:双向引用导致的IOS内存泄漏(中)- IOS不为人知的Bug 发现业务代码有一个地方的内存没释放,原因很也简单: ...

随机推荐

  1. Javaweb之JavaScript结合(二)

    1.js的String对象 ** 创建String对象 *** var str = "abc"; ** 方法和属性(文档) *** 属性 length:字符串的长度 *** 方法 ...

  2. [POJ1477]Box of Bricks

    Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 19503   Accepted: 7871 Description Litt ...

  3. sublimelinter-jshinter

    --- ocalhost:~ nihao$ sudo npm install jshint -gPassword:/usr/local/bin/jshint -> /usr/local/lib/ ...

  4. Bzoj 1562: [NOI2009]变换序列 匈牙利算法,二分图匹配

    题目: http://cojs.tk/cogs/problem/problem.php?pid=409 409. [NOI2009]变换序列 ★★☆   输入文件:transform.in   输出文 ...

  5. shell脚本应用(2)--变量,数值和字符串

    变量 定义,赋值: var=value 引用 $var,${var} 特殊变量 $?上条命令状态 $*/$@所有参数列表 $#参数个数 $0执行的命令名称 $1/${10}第1/10个参数 数值运算 ...

  6. bootstrap折叠修改hover

    $('div.panel-collapse').on('shown.bs.collapse hidden.bs.collapse', function() { $(this).dequeue('col ...

  7. 【三支火把】---常用C语言控制台函数总结(持续更新)

    写了这么久的C程序,每次看到输出的结果都是从上往下排列的黑白框,有没有感觉很无聊啊?今天再次总结一个常用的控制台函数,能够帮助你做好一个好看的界面. 1.设置光标位置代码如下: int main(vo ...

  8. 编程实例--for循环,找出0~100之间与8有关的正整数

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. 一个tomcat究竟能接受多少并发

    maxThreads 对tomcat来说,每一个进来的请求(request)都需要一个线程,直到该请求结束.如果同时进来的请求多于当前可用的请求处理线程数,额外的线程就会被创建,直到到达配置的最大线程 ...

  10. 用WebCollector爬取站点的图片

    用WebCollector爬取整站图片,仅仅须要遍历整站页面.然后将URL为.jpg.gif的页面(文件)保存到本地就可以. 比如我们爬取一个美食站点,获取里面全部的图片: import cn.edu ...