0

我知道這個問題之前已經被問過,但沒有解決方案解決我的問題,所以我再次問這個問題。我試圖通過一個塊的回調來調用自我的方法。我收到以下錯誤:Objective-C正確使用ARC塊?

在此塊捕獲的「自我」強烈很可能會導致一個保留週期

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    self.webClient.completionHandler = ^{ 
     [self populateData]; 
    }; 
} 

我試圖做類似下面的代碼,我仍然得到相同的警告。 解決方案是什麼?

__weak id myself = self; 
[myself populateData]; 
+1

你是否在塊內放置__weak行?如果是這樣,它需要在設置完成處理程序/定義塊的行之前。 – UIAdam

+0

yes right before [self populateData] – aryaxt

+0

有沒有一種更清潔的方法能夠做到塊內的一切? – aryaxt

回答

4

您的代碼應該是這樣的:

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    __weak id weakSelf = self; 
    self.webClient.completionHandler = ^{ 
     [weakSelf populateData]; 
    }; 
} 
0

UIAdam給出了正確的答案,但它是值得理解爲什麼它是正確的。

首先,你爲什麼得到警告?

自我對webClient有很強的參考價值。 webClient對completionHandler有很強的參考價值。 completionHandler對自我很有借鑑意義。因此,如果程序中的所有其他引用都消失了,這個循環中的每個項目仍然有很強的參考,所以它們永遠不會被釋放。

__weak id myself = self; 
[myself populateData]; 

當然不工作的嘗試。該塊仍然引用自我,因爲它將它分配給我自己。所以這裏沒有區別。

__weak ID weakSelf =自我UIAdam的解決方案; self.webClient.completionHandler =^{weakSelf populateData]; };

意味着weakSelf是一個弱引用,並且該塊只包含對自我的弱引用。所以如果所有其他對自我的強烈引用都消失了,那麼只剩下一個弱引用。弱引用不會讓自己活着,所以自我被釋放。

現在如果發生這種情況,但是其他的東西對webClient有強烈的參考,並且您的塊被調用? weakSelf是一個弱引用,當對象被釋放時弱引用被設置爲零。所以你必須做好準備,當你的街區被叫時,weakSelf是零的。它實際上更好寫

id strongSelf = weakSelf; 
[strongSelf populatedData]; 

塊內:strongSelf可能被設置爲零,或者它會被設置爲自我。但由於它是一個強有力的參考,它將保持非零,直到塊完成。如果不是零開始。

+0

「實際上寫得更好」在這種情況下,沒有區別。 – newacct