• Block中的引用循环


    原文地址: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,累啊,希望下个月能多分享一些内容,希望大家都能有所收获,还是那句话,如果文中有不对的地方,望指正,谢谢。
  • 相关阅读:
    字符串基本操作
    条件、循环、函数定义 练习
    turtle库基础练习
    Python基础练习
    AutoLayout 教程
    Mac上最佳的SVN管理工具:Cornerstone
    图片上传 关于压缩的问题
    关于单元测试的问题
    获取ios设备的当前IP地址
    关于项目使用ARC的管理方式
  • 原文地址:https://www.cnblogs.com/lujianwenance/p/5910490.html
Copyright © 2020-2023  润新知