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

哇草,成功了!计数器为2,正常释放了,看来自己的想象力,还是可以的!!
接下来,我们补充完善一下代码,增加一个reloadData方法,方法里调用事件。
完整的代码如下:
@interface BlockTable : NSObject
typedef void (^AddCellBlock)();
@property (nonatomic,copy)AddCellBlock addCell;
-(void)reloadData;
@end
@implementation BlockTable
-(void)setAddCell:(AddCellBlock)addCell
{
__weak AddCellBlock addCellWeak=addCell;
_addCell=addCellWeak;
}
-(void)reloadData
{
if(self.addCell)
{
self.addCell(); self.addCell();//没事来两次,模拟table多次循环清加cell
}
}
-(void)dealloc
{
NSLog(@"Table relase");
}
@end
修改一下增加日志输出,现在再执行一下看看:

一切看起来都相当完美,不需要引入第三,需要多次使用的,只是在存的时候,存个弱引用,就搞定了。
6:弱引用降低计数的缺陷:
块的定义,和使用的场景,必须在同一个函数。
说白了就是块离开函数体就会消亡,所以要用要赶紧,且用且珍惜。
正常一个Table写完代码reloadData后,数据出来了。










