2015-09-08 38 views
1

我已經一直在收到警告使用「自我」警告:沒有當我試圖用塊的「自我」,直到這時候塊

__weak typeof(self) weakself = self; 
[self.segmControl setSegmPosition:^(int position) { 
    [weakself.scrollView scrollRectToVisible:CGRectMake(self.view.size.width*position, 0, weakself.view.size.width, weakself.view.size.height-10) animated:YES]; 

[weakself.segmControl setScrlView:position]; 
}]; 
[self.view addSubview:self.segmControl]; 

enter image description here

+6

你應該發佈實際的代碼而不是屏幕截圖 – Paulw11

+1

@ Paulw11我怎樣才能顯示沒有「實際代碼」的警告? – Edward

+0

你可以用註釋突出顯示有問題的行,或者你可以包含代碼和屏幕截圖 – Paulw11

回答

7

這並不總是使用問題self在一個塊中;如果編譯器認爲這樣做會導致循環引用,則會發出警告。也就是說,在塊中使用self會導致塊保留self引用的對象;除非self對象也對塊有強烈的參考,否則沒什麼大不了的。

您發佈的代碼的形式爲:

[self.foo method:^{ [self bar]; }] 

這不是很明顯的一個問題。該塊將捕獲self,但隨後您將它傳遞給self僅保存引用的對象上的方法。它可能創建一個循環引用,但它可能不會。我們必須知道方法內部會發生什麼,編譯器很難確定這一點;即使你有方法method:的源代碼,編譯器也不能確定你是在運行時調用該實現。

對比度與:

self.foo = ^{ [self bar]; } 

在這種情況下,該塊被捕獲self並保持到一個強引用(假設foo被定義爲@property (strong))的塊。在這種情況下,編譯器可以或多或少確定您在此創建循環引用,因此它會警告您。

+0

謝謝你的答案。實際上,這個特殊的「自我」造成了很大的內存泄漏,但現在我知道爲什麼了。 – Edward

+0

@愛德華這並不奇怪。就因爲沒人喊「鴨子!」並不意味着你不會被球擊中。 :-) – benzado

+2

或者因爲這件事而被鴨子擊中。 :)(好的回答。投票) –

相關問題