2011-10-09 61 views
1

這是我所看到的,當我運行下面的代碼:NSMutableArray的財產 - 發行兒童

// Dealloc on MyClass not called 
MyClass* c = [MyClass new]; 
self.a = [NSMutableArray new]; 
[self.a addObject:c]; 
[c release]; 
[a release]; 

// Dealloc on MyClass called 
MyClass* c2 = [MyClass new]; 
NSMutableArray* a2 = [NSMutableArray new]; 
[a2 addObject:c2]; 
[c2 release]; 
[a2 release]; 

// Dealloc on MyClass called 
MyClass* c3 = [MyClass new]; 
a = [NSMutableArray new]; 
[a addObject:c3]; 
[c3 release]; 
[a release]; 

爲什麼dealloc中不會被調用的第一個例子嗎?

編輯:

我想我是誤解了這一切。基本上我需要做的是:

NSMutableArray* alocal = [NSMutableArray new]; // alocal has a retain count of 1 
self.a = alocal; // a has a retain count of 1 
[alocal release]; // alocal has a retain count of 0 
[a release]; // a has a retain count of 0 

OR

self.a = [[NSMutableArray new] autorelease]; // a has a retain count of 2 
[a release]; // a has a retain count of 0 

OR

self.a = [NSMutableArray array]; // a has a retain count of 2 
[a release]; // a has a retain count of 0 

正如一個音符,與自動釋放/陣列選項(#2,#3), a不會馬上釋放,所以如果你想要更多的控制,請使用選項#1。

謝謝!

+0

有趣的...所以基本上你希望它在那一刻被釋放吧?這聽起來很公平。通常我們只是讓游泳池自動釋放,但你是對的,它不會立即釋放。 – raixer

回答

3

因爲在第一個例子中,假設a是保留/複製屬性,數組泄漏。

self.a = [NSMutableArray new]; 

其中,順便說一句,與第三實施例不同:

a = [NSMutableArray new]; 

在第三種情況下,對象被直接分配到的ivar(不涉及屬性setter)。

回到第一個例子,方法new返回一個保留對象(+1),然後屬性設置器保留對象(+2)。然後,當財產被釋放(-1)時,你最終得到+1。這是錯誤的。你需要平衡你的保留/釋放以+0結束。

一個簡單的解決方案是使用一個便捷構造

self.a = [NSMutableArray array]; 

在這種情況下,返回array一個自動釋放物體(0)和屬性setter的方法保留了對象(1),這是由財產釋放(-1)平衡,你最終+0。


此外,在第一示例中,您鬆開穿過的ivar設置的屬性的對象:

[a release]; 

其結果是,該屬性現在保持一個指針到一個潛在的解除分配對象。由於您放棄了對象的所有權,因此不能保證該對象將來還活着。如果該對象實際上已被釋放(因爲它沒有任何其他所有者),則您的指針仍將指向該對象曾經居住的堆的內存地址;除了現在,該地址可能包含任何內容:所述對象的舊位模式或不相關對象或絕對垃圾。

如果您將消息發送到釋放對象,例如,它會讓你的應用崩潰。爲了避免這種情況,通過屬性釋放對象:

self.a = nil; 
+0

當我做... self.a = [NSMutableArray數組]; dealloc仍然沒有被調用。另外當我調用... self.a = [[NSMutableArray new] autorelease]; dealloc仍然沒有被調用。 – user472292

+0

@ user472292既然數組不再泄漏,它應該被調用。必須有其他事情正在進行。你能提供更多細節嗎? – albertamg

+0

我很確定陣列沒有泄漏。在我打電話給[發佈]之前,我檢查了保留計數,結果爲1. – user472292

0

這取決於你如何實現財產「A」 它應該是:

@property (retain) NSMutableArray *a; 

也使用「新」它是把分配,所以你應該自動釋放它像這樣的時候:

self.a = [[NSMutableArray new] autorelease]; 
+0

當我做... self.a = [NSMutableArray數組]; dealloc仍然沒有被調用。另外當我調用... self.a = [[NSMutableArray new] autorelease]; dealloc仍然沒有被調用。 – user472292