关于block 使用__weak & __strong 来解决循环引用的问题
__weak&__strong的使用解释
先摘抄一段来自AFNetworking的一段代码:
__weak __typeof(self)weakSelf = self;
AFNetworkReachabilityStatusBlock callback = ^(AFNetworkReachabilityStatus status) {
__strong __typeof(weakSelf)strongSelf = weakSelf;
strongSelf.networkReachabilityStatus = status;
if (strongSelf.networkReachabilityStatusBlock) {
strongSelf.networkReachabilityStatusBlock(status);
}
};
我们知道使用weakSelf的作用是为了防止强循环引用, 产生不必要的内存泄漏问题. 但是为什么在block内部还要重新转成strongSelf.
究其原因, 因为在block内部的weakSelf有可能为为self或者为nil (比如当前界面正在加载网络数据, 而此时用户关闭了该界面). 这样在某些情况下代码会崩溃. 所以为了让self不为nil, 我们在block内部将weakSelf转成strongSelf. 当block结束时, 该strongSelf变量也会被自动释放. 既避免了循环引用, 又让self在block内部不为nil.
故为了保证self在block执行过程里一直存在,对他强引用strongSelf
————————————————
以上是网上大家的回答,但这并没有说明白为什么作者没有直接使用 self, 或者这样就可以打破循环了??
其实这么写的意义在于: weakSelf 时,block 捕获到了一个self 的弱引用,block在结构体内会弱持有这个self, 所以block和self 之间不会形成循环引用, 同时block里加了一个strong 这样的话又使得 Self 的returnCount + 1,(strongSelf是一个局部变量,block执行完即会被释放,weakSelf则是保存在block结构体中的变量,是随着block进行释放的)这样操作下来既解决了循环引用,又让self的使用变得安全了。
切记: __strong并没有让Block对self 变成强持有,而只是使returnCount+1。 所以必须要这么操作1. 先弱持有self 2. 使self returnCount + 1。
再啰嗦两句理解这个需要两个基本认知:
- block持有的weakSelf 和局部变量strongSelf释放时机不一样(即Block持有两个变量,但是两个变量的生命周期不一样),所以同样都是使self 保持returnCount + 1,但是强引用会导致循环引用而__weak&__strong来回倒腾一下就避免了这个问题。
- 2.__strong并没有使self变成强引用,block依然只是持有了一个weakSelf,__strong 只是定义了一个 returnCount+1的strongSelf。
希望我说明白了~~
网友评论