一 :前言
在Block 的使用中 为了避免循环引用 我们经常把 ‘self’ 转换成 weak automatic 的变量 这样在 Block 中就不会出现对 self 的强引用。代码示意 如下所示:
__weak __typeof__(self) weakSelf = self; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[weakSelf doMethod];
});
但是 在 AFNetworking 的有如下代码。 这里 Matte 使用了 strongSelf 修饰。
__weak__typeof(self)weakSelf =self;
AFNetworkReachabilityStatusBlock callback = ^(AFNetworkReachabilityStatus status) {
__strong__typeof(weakSelf)strongSelf = weakSelf;
strongSelf.networkReachabilityStatus= status;if(strongSelf.networkReachabilityStatusBlock) {
strongSelf.networkReachabilityStatusBlock(status);
}
};
在 博客 中 我们讲到三种 解决循环引用的方法。其实在 也是可以使用 StrongSelf 的。那么 在什么情况下使用 strongSelf
什么情况下使用weakSelf 呢?
在博客 https://dhoerl.wordpress.com/2013/04/23/i-finally-figured-out-weakself-and-strongself/ 中讲到
__weak __typeof__(self) weakSelf = self;
dispatch_group_async(_operationsGroup, _operationsQueue, ^
{
[weakSelf doSomething];
[weakSelf doSomethingElse];
} );
Well, in this case, its possible for ‘weakSelf’ to be non-nil for the first method, but not for the second. Hmmm – the above is a simple example, most real code would get much more complex with other usages of ‘weakSelf’.
也就是 在实际调用过程中 weakSelf 在执行完 doSomething 方法后 可能 会变成nil 。 下面我们使用代码 来演示 其中的一种情形。 如果你 发现了其他的情形 欢迎联系我。
二 : 代码演示
下载 代码DEMO https://github.com/LoveHouLinLi/iOS_Block 。
ViewController 中 方法 doSomething 是一个 耗时大约 5s 的操作
- (void)doSomething
{
// 耗时的操作
doublesum =0.0;
for(inti =0; i<1000; i++) {
for(intj =0; j<1000; j++) {
sum+=i;
sum+=j;
for(intm =0; m<1000; m++) {
sum+=m;
}
}
}
}
方法 - (void)doOtherSomething 也是一个耗时大约 5s的 方法。
按钮 操作如下
/**
反复的调用 testWeakSelf
@param sender sender description
*/
- (IBAction)blockTestThree:(id)sender
{
[selftestWeakSelfNilFailure];
}
- (IBAction)setWeakSelfNil:(id)sender
{
//weakSelf = nil;
//self = nil;
//
}
- (IBAction)strongSelf:(id)sender
{
[selftestStrongSelfInBlock];
}
从 RootViewController 点击next 进入ViewController ,点击按钮 testWeakSelfNilFailure 等3s 在 doSomething 执行完之前 点击 左上角返回按钮。 这是打印
2017-12-11 18:33:21.168596+0800 Block_Recycle[21357:5594567] do somthing end
2017-12-11 18:33:21.168698+0800 Block_Recycle[21357:5594567] weakSelf is (null)
2017-12-11 18:33:21.168729+0800 Block_Recycle[21357:5594476] view controll dealloc
再 从 RootViewController 点击next 进入ViewController ,点击按钮strongSelf 等3s 在doSomething 执行完之前 点击 左上角返回按钮。 这是打印
2017-12-11 18:33:33.128204+0800 Block_Recycle[21357:5594566] do somthing end
2017-12-11 18:33:33.128276+0800 Block_Recycle[21357:5594566] do other something start
2017-12-11 18:33:39.753628+0800 Block_Recycle[21357:5594566] do other thing end
2017-12-11 18:33:39.753759+0800 Block_Recycle[21357:5594476] view controll dealloc
对比发现 使用weakSelf 的场景 没有执行 完 doOtherSomething 方法里面的代码 就 dealloc 了 而 使用 strongSelf 的场景一直 等到 doOtherSomething 执行完之后 才 dealloc !!!!
实际开发过程中 我们 尽量使用 StrongSelf 因为我们不知道 合作coder 啥时候 释放了 self 造成 代码没执行完就 被设置为 nil 的 问题。 代码 和 解决 Block 循环引用一起 注意区分。
三:参考博客
http://www.jianshu.com/p/36342264d6df
https://dhoerl.wordpress.com/2013/04/23/i-finally-figured-out-weakself-and-strongself/