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

2020-01-21 04:05:19王旭

前言:

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

对于新手,学到的文章都在教你用:typeof(self) __weak weakSelf = self

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

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

1:从引用计数器开始:

这里先设计一个TableBlock类:


@interface BlockTable : NSObject

typedef void (^AddCellBlock)();
@property (nonatomic,copy)AddCellBlock addCell;@end

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


@interface BlockTable : NSObject
typedef void (^AddCellBlock)();
@property (nonatomic,copy)AddCellBlock addCell;@end

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

ios,block,weakself,weak,self,弱引用self

这时候它的引用数是1,并且出了Table relase 。

接着给addCell属性赋一个值,并运行:

ios,block,weakself,weak,self,弱引用self

一个空的事件,里面并没有引用到table,所以引用数还是1。

2:开始循环引用

在block引用table,让它产生循环引用,并运行:

ios,block,weakself,weak,self,弱引用self

我们看到:引用数变成了3,没有输出对象释放信息了,为啥不是2呢?大大的问号!!

一个属性赋值,为什么增强两个引用计数?

3:猜解跳跃的计数器

接下来,把属性设置为nil,运行看看:

ios,block,weakself,weak,self,弱引用self

设置为nil,还有2?

也正常释放了?

为了证实自己对这个看起来就很明显的猜想:重写addCell的setter方法,不进行任何保存:


@implementation BlockTable
-(void)setAddCell:(AddCellBlock)addCell
{
 
}

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

ios,block,weakself,weak,self,弱引用self