原文地址: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. Java语言使用HttpClient模拟浏览器登录

    使用HttpClient来模拟浏览器登录网站,然后可以进行操作,比如发布信息等 第一步:获取实际的post网址,(不考虑复杂情况下) 1.需要使用到firefox的httpfox插件,httpfox中 ...

  2. CosCos2D-android 代码总结

    CosCos2D-android 学习总结 资料: Android游戏开发视频教程 Cocos-android-1代码包下载 直接上代码: MainActivity中Cocos常规写法: //coco ...

  3. Detect combined string

    写一个程序判断字符串A是否为其他两个字符串的组合,组合过程中其他两个字符串的相对顺序不能被破坏. 举例说明:abc和def可以组成字符串adebcf,但不能组成aefbcd,因为def的相对顺序已经被 ...

  4. [读书笔记]算法(Sedgewick著)·第一章(2)

    接着上一篇,mindmap更新如下内容. 3.背包.队列和栈 这节主要讲述了这三种数据结构(Bag.Queue.Stack)的API.实现以及链表.Queue和Stack还含有删除元素的方法.并引出了 ...

  5. jQuery获取鼠标移动方向

      <!doctype html>   <html>       <head>   <meta http-equiv="Content-Type&q ...

  6. 使用sessionStorage得一个坑

    1.首先sessionStorage.setItem("isMybill" false) 2.使用的时候 sessionStorage.getItem('isMybill')  / ...

  7. HTML5 Canvas动画效果演示

    HTML5 Canvas动画效果演示 主要思想: 首先要准备一张有连续帧的图片,然后利用HTML5 Canvas的draw方法在不同的时间 间隔绘制不同的帧,这样看起来就像动画在播放. 关键技术点: ...

  8. C# 基础知识 protected 关键字

    using System;using System.Collections.Generic;using System.Linq;using System.Text; namespace Console ...

  9. iOS-iPhone系统版本号-iPhone App版本号

    转载: http://blog.sina.com.cn/s/blog_7b9d64af0101bu9j.html 很多时候,我们需要获得用户iPhone版本号,或者App的当前版本号. 关心以下两个方 ...

  10. SQL Server 排序函数 ROW_NUMBER和RANK 用法总结

    下面的例子和SQL语句均在SQL Server 2008环境下运行通过,使用SQL Server自带的AdventureWorks数据库. 转载请注明此文原创自 CSDN TJVictor的专栏:ht ...