一 :前言
在Block 的使用中 為了避免循環(huán)引用 我們經(jīng)常把 ‘self’ 轉(zhuǎn)換成 weak automatic 的變量 這樣在 Block 中就不會(huì)出現(xiàn)對(duì) self 的強(qiáng)引用。代碼示意 如下所示:
__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);
}
};
在 博客 中 我們講到三種 解決循環(huán)引用的方法哮幢。其實(shí)在 也是可以使用 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’.
也就是 在實(shí)際調(diào)用過程中 weakSelf 在執(zhí)行完?doSomething 方法后 可能? 會(huì)變成nil? 钝的。 下面我們使用代碼 來(lái)演示 其中的一種情形及塘。 如果你 發(fā)現(xiàn)了其他的情形 歡迎聯(lián)系我。?
二 : 代碼演示
下載 代碼DEMO?https://github.com/LoveHouLinLi/iOS_Block? ?绵跷。
ViewController 中 方法??doSomething? 是一個(gè) 耗時(shí)大約 5s 的操作?
- (void)doSomething
{
// 耗時(shí)的操作
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? 也是一個(gè)耗時(shí)大約 5s的 方法膘螟。
按鈕 操作如下?
/**
反復(fù)的調(diào)用 testWeakSelf
@param sender sender description
*/
- (IBAction)blockTestThree:(id)sender
{
[selftestWeakSelfNilFailure];
}
- (IBAction)setWeakSelfNil:(id)sender
{
//weakSelf = nil;
//self = nil;
//
}
- (IBAction)strongSelf:(id)sender
{
[selftestStrongSelfInBlock];
}
從 RootViewController? 點(diǎn)擊next 進(jìn)入ViewController? ,點(diǎn)擊按鈕?testWeakSelfNilFailure 等3s? 在?doSomething 執(zhí)行完之前 點(diǎn)擊 左上角返回按鈕碾局。 這是打印
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? 點(diǎn)擊next 進(jìn)入ViewController? 荆残,點(diǎn)擊按鈕strongSelf 等3s? 在doSomething 執(zhí)行完之前 點(diǎn)擊 左上角返回按鈕。 這是打印
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
對(duì)比發(fā)現(xiàn) 使用weakSelf 的場(chǎng)景 沒有執(zhí)行 完?doOtherSomething 方法里面的代碼 就 dealloc 了 而 使用 strongSelf 的場(chǎng)景一直 等到??doOtherSomething 執(zhí)行完之后 才?dealloc >坏薄D谒埂!像啼!?
實(shí)際開發(fā)過程中 我們 盡量使用 StrongSelf? 因?yàn)槲覀儾恢?合作coder 啥時(shí)候 釋放了 self 造成 代碼沒執(zhí)行完就 被設(shè)置為 nil 的 問題俘闯。 代碼 和 解決 Block 循環(huán)引用一起 注意區(qū)分。
三:參考博客
http://www.reibang.com/p/36342264d6df
https://dhoerl.wordpress.com/2013/04/23/i-finally-figured-out-weakself-and-strongself/