2013-04-17 50 views
10

避免了「在此塊強烈捕捉自我很可能會導致保留週期」每次我必須使用全局變量或財產這樣的塊中的時間信息

self.save = ^(){ 
    if (isItSaving == NO) { 
     [self saveMyFile]; 
    } 
}; 

我不得不重寫這就像

BOOL *iis = isItSaving; 
id myself = self; 

self.save = ^(){ 
    if (iis == NO) { 
     [myself saveMyFile]; 
    } 
}; 

或Xcode中會抱怨「在此塊強烈捕捉自我很可能會導致保留週期...

它抱怨甚至對布爾變量?

在塊之前重新聲明所有內容似乎是一個蹩腳的解決方案。

這是正確的方法嗎?有沒有一種優雅的方式?

這東西很醜。我正在使用ARC。

回答

20

該問題僅在顯式或隱式地從塊內引用self時纔會發生。訪問全局變量時不會發出警告。

就你而言,你可能訪問過一個(boolean)伊娃。訪問ivar默認使用self,這就是爲什麼編譯器警告(正確)關於保留週期的原因。

修復保留週期的常用方法是:

typeof(self) __weak weakSelf = self; 

self.save = ^() { 
    typeof(weakSelf) __strong strongSelf = weakSelf; 
    if (strongSelf != nil && ! strongSelf->isItSaving) { 
     [strongSelf saveMyFile]; 
    } 
}; 

...,是的,這是一個有點塊的一個醜陋的一部分。

+1

男人,這是醜陋的地獄。不得不重新宣佈一切......謝謝。 – SpaceDog

+0

@MarkAmery是的,鏗鏘聲越來越多的問題。並且這是正確的,封閉對象的生命週期應至少延長到塊完成。編輯... –

+1

@NikolaiRuhe *「封閉對象的生命週期應該至少延長到塊完成」* - 很好,我一開始並沒有注意到爲什麼在塊中創建一個強烈的'self'引用的任何原因會優於使用'__unsafe_unretained',但這個短語使得它非常清晰。如果你願意,甚至可以在你的答案中比較兩種方法。 –

4

使用__unsafe_unretained typeof(self) weakSelf = self;

+0

我想你不能使用__unsafe_unretained與ARC – SpaceDog

0

除了@ NikolaiRuhe的反應,在你的榜樣聲明屬性

BOOL *iis = isItSaving; 
id myself = self; 

時暗示strong引用,所以使用__weak自我,防止保留週期。那麼你可能會想知道爲什麼你需要聲明一個__strong參考塊內的弱自我,這是爲了確保它在塊的生命週期內不會被釋放,否則weakSelf->isItSaving將會中斷,如果self被釋放。

相關問題