iOS block中weakSelf和strongSelf的使用

2019-06-13  本文已影响0人  彗星来的那一夜

一 :前言

在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 。 下面我们使用代码 来演示 其中的一种情形。 如果你 发现了其他的情形 欢迎联系我。

二 : 代码演示

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/

上一篇下一篇

猜你喜欢

热点阅读