之前看到很多使用 block 的代碼中都有 StrongSelf,一直不懂為啥,今天研究了一下.總算弄懂了一些.
iOS 中內(nèi)存管理一直以來都是比較麻煩的部分.尤其是在 block 中,如果稍有不慎,就會造成循環(huán)引用.為了解決這個問題,經(jīng)常會用到 weakself.
例如
__weak __typeof__(self) weakSelf = self;
self.onFailBlock=^{
[weakSelf doSomething];
} );
看似搞定了,其實會有一定隱患.
如果 self 在一定時間之后會被釋放,那么就可能出現(xiàn)在 block運行中途被釋放.
例如以下代碼
__weak __typeof__(self) weakSelf = self;
self.onFailBlock=^{
[weakSelf doSomething];
[weakSelf doSomethingElse];
} );
doSomething中的 WeakSelf還沒有被釋放, Weakself還不是 nil,到 doSomethingElse的時候,就被釋放了,那么doSomethingElse就不能成功執(zhí)行.
那要怎么辦?
要死一起死!
在執(zhí)行 block中代碼之前,首先將用一個局部變量強持有,這樣就會有兩種情況,一種是持有之前就釋放了,那就拜拜了,后面代碼都不執(zhí)行.另一種,是執(zhí)行之前還在,沒被釋放,那么由于有一個局部變量強持有, self 暫時就不會被釋放,到這個 block 運行結束,那么,如果沒有其他對象持有, self 就成功被釋放了.
代碼如下
__weak __typeof__(self) weakSelf = self;
self.onFailBlock=^{
__typeof__(self) strongSelf = weakSelf;
[strongSelf doSomething];
[strongSelf doSomethingElse];
} );
ps:順便一提,如果你使用了 ReactiveCocoa,也可以用@ weakify 和@ strongify來簡化操作,可參考為什么你應該開始使用@weakify和@strongify 宏定義
代碼可以縮減為
@weakify(self);
self.onFailBlock=^{
@strongify(self);
[self doSomething];
[self doSomethingElse];
} );
weakify 和__weak __typeof__(self) weakSelf = self;一樣,創(chuàng)建一個 weak 引用.
strongify和__typeof__(self) strongSelf = weakSelf;類似,只不過它創(chuàng)建的局部變量名字就叫做 self.