2011-10-03 52 views
0

在我分析了我的代碼之後,Xcode指出了潛在的泄漏,如下所示。 Screenshot of code with analysis results潛在的物體泄漏警告 - 需要澄清

這是不是我應該關心?

在這段代碼中,設置doublyLinkedList類是唯一擁有者,並繼續管理整個程序執行此對象。

+0

你如何發佈* dll? – 5StringRyan

+0

在'dealloc'下面,我有['[self doublyLinkedList] release]' – JAM

回答

1

您不妨這樣做,而不是:

if (self) { 
    DoublyLinkedList *dll = [DoublyLinkedList new]; 
    self.doublyLinkedList = dll; 
    [dll release]; 
} 

在標題中,聲明doublyLinkedList即保留了@property

+0

如果你賦值了'[self setDoublyLinkedList:[DoublyLinkedList new]];'你會如何釋放它呢?它應該是'[self setDoublyLinkedList:[[DoublyLinkedList new]] autorelease];'在這種情況下? – JAM

+0

是的,autorelease那裏。但請確保將doublyLinkedList的@property設置爲保留。 – mahboudz

+0

總是寫出最佳可讀性的代碼。如果這樣做'[self setDoublyLinkedList:[[DoublyLinkedList new] autorelease];'最適合你,那就這樣吧。我喜歡將事情分解開來,以便下一位程序員可以輕鬆檢查它們,或者如果我想在StackOverflow上尋求幫助。 – mahboudz

3

你得到警告的原因是因爲new調用返回一個保留的對象,然後你的setter可能正在做另一個retain(取決於它是合成的還是手動生成的)。

此外,我建議您使用標準alloc/init而不是new,以便兩階段創建顯而易見。

這是更好的:

if (self) { 
    DoublyLinkedList *dll = [[[DoublyLinkedList alloc] init] autorelease]; 
    self.doublyLinkedList = dll; 
} 

或只是

if (self) { 
    self.doublyLinkedList = [[[DoublyLinkedList alloc] init] autorelease]; 
} 
+0

酷;謝謝! – JAM

0

如果你有一個名爲 「doublyLinkedList」 屬性(假設基於給定的代碼),它是 「保留」,就可以請執行以下操作:

​​
1

您有「潛在泄漏」,因爲分析器發現您已分配了內存對於DoublyLinkedList實例(使用new),將其放入名爲dll的局部變量中,而不是在相同範圍內釋放該內存。

假設doublyLinkedList會員,你設置恰好也是聲明爲retain ING的屬性,你也有一個實際泄漏,因爲你有過保留,你在這裏創建DoublyLinkedList

ownership rules表示您對此實例有一個聲明,因爲您調用了new來創建它。當您將實例傳遞給setDoublyLinkedList:時,它將被保留,然後您有兩個索賠。當init方法結束時,通過ivar/property只有一個對實例的引用 - 你已經失去了局部變量 - 這意味着你有更多的所有權聲明比你有參考。這是一個很好的跡象表明你會有泄漏。

修理泄漏,你需要放棄init方法結束之前,你的要求之一。

DoublyLinkedList * dll = [DoublyLinkedList new]; 
[self setDoublyLinkedList:dll]; 
[dll release]; 

autorelease:您可以通過以下兩種方式之一,一旦該屬性設置做到這一點,利用release

[self setDoublyLinkedList:[[DoublyLinkedList new] autorelease]]; 
// Or equivalent procedures involving a temp variable 

但是,應該注意的是,使用initmay be problematic制定者(另請參閱Mike Ash's writeup on the topic),因爲訪問者可能 - 可能 - 具有取決於您的對象已完全設置的副作用。似乎有在這個問題上兩大陣營,這可能是最好的瞭解,並得出自己的結論,但你會發現,它簡化了您的初始化方法分配給高德,而不是使用屬性:

if(self){ 
    doublyLinkedList = [DoublyLinkedList new]; 
} 

這在內存管理方面完全正確。

最後,如果DoublyLinkedList是您的代碼的類,您還可以考慮編寫一個便捷構造函數,它將爲您返回一個新的自動釋放實例。在可可的約定是簡單地將類命名後的方法,用標準方法名外殼,像這樣:

+ (id) doublyLinkedList { 
    return [[[self alloc] init] autorelease]; 
} 

注意,這是一個類方法:

if(self){ 
    [self setDoublyLinkedList:[DoublyLinkedList doublyLinkedList]]; 
} 

,看到my answer to "Self-allocating objects"爲這些構造函數的解釋。