2014-12-05 17 views
1

OK,在這個ARC保持代碼的自我塊內:這會把自己抱在一個塊裏面嗎?

dispatch_async(someQ, ^{ 
    [self doSomething]; 
}); 

,並可以通過

__weak MyRequest *weakSelf = self; 
dispatch_async(someQ, ^{ 
    [weakSelf doSomething]; 
}); 

但如果DoSomething的有很多自我引用什麼來解決?因爲doSomething代碼將在block內部運行,並不是doSomething的所有代碼都是直接在block上運行的嗎?

我是否需要將weakSelf傳遞給doSomething以便該方法可以使用weakself引用而不是self?喜歡的東西

__weak MyRequest *weakSelf = self; 
dispatch_async(someQ, ^{ 
    [weakSelf doSomethingUsingThisSelf:weakself]; 
}); 
+0

'doSomething'已經在弱引用上調用。 – rmaddy 2014-12-06 00:48:46

+0

是的,我知道但裏面doSomething有一堆引用自我... – SpaceDog 2014-12-06 01:01:57

+0

10那麼,這有什麼問題?你需要知道'doSomething'方法中的'self'? – rmaddy 2014-12-06 01:03:26

回答

1

這樣做:

MyRequest *__weak weakSelf = self; 
dispatch_async(someQ, ^{ 
    [weakSelf doSomething]; 
}); 

...當有到self不再引用,weakSelf自動成爲nil。因此,異步回調將最終發送doSomethingnil,即使對象在回調之前被銷燬,也不會執行任何操作。

如果weakSelf不是零,它只是一個指向對象的指針。將選擇器發送給對象時,有兩個隱式參數:self_cmd(請參見documentation for IMP),第6.1節)。因此weakSelf在這些調用中成爲隱含的​​self。此時,self是一個很強的參考,因此在doSomething調用鏈期間,對象不會從下面被銷燬,但從doSomething引用self不會導致引用計數增加,因爲該塊不知道任何內容關於doSomething裏面發生了什麼。

+0

好的,謝謝。這正是我想證實的。 – SpaceDog 2014-12-06 01:04:59

+0

更糟糕的是,如果'dispatch_async'塊有多個弱引用引用,那麼其中一半可能會被髮送到對象而另一半則被傳送到零。歡迎來到異步世界:-) – Andy 2014-12-06 01:50:17

+0

那麼,如果你在同一個範圍內多次訪問一個弱引用,你至少會得到來自xcode的警告。 – 2014-12-06 02:08:27