iOS block中weakSelf和strongSelf的使用(分別什么時候用)

一 :前言

在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.lxweimin.com/p/36342264d6df

https://dhoerl.wordpress.com/2013/04/23/i-finally-figured-out-weakself-and-strongself/

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容