原文地址: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. as3+java+mysql(mybatis) 数据自动工具(三)

    介绍一下数据类配置,该数据类配置主要用于需要将数据库 mysql 数据转换成 java 对象,再转换为 as3 对象的数据类 配置文件为 xml 格式. <objects> <obj ...

  2. poj2192(搜索)

    这个题目对于两个字符串A,B是否可以通过规则生成C. import java.util.Scanner; public class Main { public static void main(Str ...

  3. HW4.36

    import java.util.Scanner; public class Solution { public static void main(String[] args) { Scanner i ...

  4. strust1.x中formbean的原理及作用

    from:     http://blog.csdn.net/tuiroger/article/details/3947896 今天张老师讲了一些比较重要的strust标签,<html:link ...

  5. SPOJ4206Fast Maximum Matching(hopcroft-karp)

    题目请戳这里 题目大意:裸的二分匹配. 题目分析:数据比较强,用来测模版的.这题用hungry跑着会比较吃力,所以用hopcroft-karp算法.这个算法较hungry高效是因为每次bfs找到一个增 ...

  6. linux中删除目录

    在linux中删除一个目录很简单,很多人还是习惯用rmdir,不过一旦目录非空,就陷入深深的苦恼之中,现在使用rm -rf命令即可解决. 直接rm就可以了,不过要加两个参数-rf 即:rm -rf 目 ...

  7. [置顶] Oracle job procedure 存储过程定时任务

    oracle job有定时执行的功能,可以在指定的时间点或每天的某个时间点自行执行任务. 一.查询系统中的job,可以查询视图 --相关视图 select * from dba_jobs; selec ...

  8. 10409 - Die Game

    Problem G: Die Game Life is not easy. Sometimes it is beyond your control. Now, as contestants of AC ...

  9. FireMonkey 使用Webbrowser

    DELPHI XE5 源码PASCAL:http://files.cnblogs.com/xe2011/FireMonkey_Webbrowser.rar 为了这个用上webbrowser真是费太大劲 ...

  10. jfinal拦截器301跳转

    在jfinal的handle中加入 HandlerKit.redirect301("http://10.10.3.144:8080/bbb.rar", request, respo ...