一篇文章让你看懂IOS中的块为何再也不需要WeakSelf弱引用

  

  

最近都在折腾Sagit架框的内存释放的问题,所以对这一块有些心得。

  

对于新手,学的到的文章都在教你用:<代码> typeof(自我)__weak weakSelf=自我

  

对于老的手,可能早习惯了到处了WeakSelf了。

  

这次,就来学,学如何不用WeakSelf。

  

  

这里先设计一个TableBlock类:

        @ interface BlockTable: NSObject      typedef无效(^ AddCellBlock) ();   @ property(原子、复制)AddCellBlock addCell; @end      

先这么简单,一个BlockTable只有一个块属性,然后输出一段释放的日志。

        @ interface BlockTable: NSObject   typedef无效(^ AddCellBlock) ();   @ property(原子、复制)AddCellBlock addCell; @end      

接着,随意找一个地方写写代码:来了新的一个BlockTable,并打印一下信息:

  

一篇文章让你看懂IOS中的块为何再也不需要WeakSelf弱引用“> </p>
  <p>这时候它的引用数是1,并且出了表relase。</p>
  <p>接着给addCell属性赋一个值,并运行:</p>
  <p> <img src=   @ implementation BlockTable   - (void) setAddCell: addCell (AddCellBlock)   {      }      

同时去掉置为零的代码:再运行看看:

  

一篇文章让你看懂IOS中的块为何再也不需要WeakSelf弱引用“> </p>
  <p>计数器仍为2,而且也释放了。</p>
  <p> <强>经过思考,出来了以下的结论:</强> </p>
  <p>,,,,1:块的定义本身,就会造成1次引用,不过这次引用,在块离开所在的函数时,释放时,抵消掉引用数。</p>
  <p>,,,,2:存档块的时候,会造成1次引用,而这个引用,是内存无法释放的原因。</p>
  <h3> </h3>
  <p>只要块的代码只执行1次的,都可以任性的自我或其它强引用。</p>
  <p>事实上,我们写的代码,很多块的确只执行一次,不管是传的时候就执行,还是传完之后过段时间回调再执行。</p>
  <p>认定只要执行1次的,就不需要WeakSelf,除非第三方框架的设计者造孽留坑,忘了在存档块执行后补上块=nil这一刀。</p>
  <h3> </h3>
  <p>继续发挥想象力,既然存的时候,会增加一次引用,辣么,让它不增加引用不就好了:</p>
  
  <pre类=   @ implementation BlockTable   - (void) setAddCell: addCell (AddCellBlock)   {   __weak AddCellBlock addCellWeak=addCell;   _addCell=addCellWeak;   }      

我们先给这个块定义一个弱引用,然后再赋值给_addCell,运行看看:

  

一篇文章让你看懂IOS中的块为何再也不需要WeakSelf弱引用“> </p>
  <p>哇草,成功了!计数器为2,正常释放了,看来自己的想象力,还是可以的! ! </p>
  <p>接下来,我们补充完善一下代码,增加一个reloadData方法,方法里调用事件。</p>
  <p> <强>完整的代码如下:</强> </p>
  
  <pre类=   @ interface BlockTable: NSObject   typedef无效(^ AddCellBlock) ();   @ property(原子、复制)AddCellBlock addCell;   - (void) reloadData;   @end   @ implementation BlockTable   - (void) setAddCell: addCell (AddCellBlock)   {   __weak AddCellBlock addCellWeak=addCell;   _addCell=addCellWeak;   }   - (void) reloadData   {   如果(self.addCell)   {   self.addCell ();self.addCell();//没事来两次,模拟表多次循环清加细胞   }   }   - (void) dealloc   {   NSLog (@“relase一张表”);   }   @end

一篇文章让你看懂IOS中的块为何再也不需要WeakSelf弱引用