個(gè)人補(bǔ)充:?? xcode斷點(diǎn)后,點(diǎn)擊下面按鈕,可以看到指針引用導(dǎo)圖,很快能看出有沒有循環(huán)引用
一.
Objective C 的 Block 是一個(gè)很實(shí)用的語(yǔ)法楷拳,特別是與GCD結(jié)合使用,可以很方便地實(shí)現(xiàn)并發(fā)森篷、異步任務(wù)薛耻。但是营罢,如果使用不當(dāng),Block 也會(huì)引起一些循環(huán)引用問題(retain cycle)—— Block 會(huì) retain ‘self’饼齿,而 ‘self‘ 又 retain 了 Block愤钾。因?yàn)樵?ObjC 中瘟滨,直接調(diào)用一個(gè)實(shí)例變量,會(huì)被編譯器處理成 ‘self->theVar’能颁,’self’ 是一個(gè) strong 類型的變量,引用計(jì)數(shù)會(huì)加 1倒淫,于是伙菊,self retains queue, queue retains block敌土,block retains self镜硕。
解決 retain circle
Apple 官方的建議是,傳進(jìn) Block 之前返干,把 ‘self’ 轉(zhuǎn)換成 weak automatic 的變量兴枯,這樣在 Block 中就不會(huì)出現(xiàn)對(duì) self 的強(qiáng)引用。如果在 Block 執(zhí)行完成之前矩欠,self 被釋放了财剖,weakSelf 也會(huì)變?yōu)?nil。
示例代碼:
1 __weak __typeof__(self) weakSelf = self;
2? ? dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
3? ? [weakSelf doSomething];
4 });
clang 的文檔表示癌淮,在 doSomething 內(nèi)躺坟,weakSelf 不會(huì)被釋放。但乳蓄,下面的情況除外:
1 __weak __typeof__(self) weakSelf = self;
2? ? dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
3? ? [weakSelf doSomething];
4? ? [weakSelf doOtherThing];
5 });
在 doSomething 中咪橙,weakSelf 不會(huì)變成 nil,不過在 doSomething 執(zhí)行完成虚倒,調(diào)用第二個(gè)方法 doOtherThing 的時(shí)候美侦,weakSelf 有可能被釋放,于是魂奥,strongSelf 就派上用場(chǎng)了:
1 __weak __typeof__(self) weakSelf = self;
2? ? dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
3? ? __strong __typeof(self) strongSelf = weakSelf;
4? ? [strongSelf doSomething];
5? ? [strongSelf doOtherThing];
6 });
__strong 確保在 Block 內(nèi)菠剩,strongSelf 不會(huì)被釋放。
總結(jié)
在 Block 內(nèi)如果需要訪問 self 的方法捧弃、變量赠叼,建議使用 weakSelf。
如果在 Block 內(nèi)需要多次 訪問 self违霞,則需要使用 strongSelf嘴办。
原文作者: lslin
原文鏈接: http://blog.lessfun.com/blog/2014/11/22/when-should-use-weakself-and-strongself-in-objc-block/
版權(quán)聲明:自由轉(zhuǎn)載-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0
二.
block是控制器的屬性,如果block內(nèi)部沒有使用weakSelf將會(huì)造成內(nèi)存泄露
self.testBlock = ^()
{
NSLog(@"%@",self.mapView);
};
self.testBlock();
把block內(nèi)部抽出一個(gè)作為self的方法买鸽,當(dāng)使用weakSelf調(diào)用這個(gè)方法涧郊,并且這個(gè)方法里有self的屬性,block不會(huì)造成內(nèi)存泄露
self.testBlock = ^()
{
[weakSelf test];
};
-(void)test
{
NSLog(@"%@",self.mapView);
}
當(dāng)block不是self的屬性時(shí)眼五,block內(nèi)部使用self也不會(huì)造成內(nèi)存泄露
TestBlock testBlock = ^()
{
NSLog(@"%@",self.mapView);
};
[self test:testBlock];
當(dāng)使用類方法有block作為參數(shù)使用時(shí)妆艘,block內(nèi)部使用self也不會(huì)造成內(nèi)存泄露
[WDNetwork testBlock:^(id responsObject) {
NSLog(@"%@",self.mapView);
}];
文/iOSWoden
原文鏈接:http://www.reibang.com/p/c6ca540861d9