2012-09-08 52 views
1

我有這樣的代碼:創建對象時應該[保留]還是[釋放],然後將其添加到矢量?

vector<SoundObject*> sounds ; 

- (void) loadSound:(NSString*) name 
    { 
    SoundObject* so = [[[SoundObject alloc] init] load:name] ; 
    if(so) 
     sounds.push_back(so) ; 
    } 

好了,所以我做了幾件事情在這裏(我可能會在這個非常小白,只是專注於內存泄漏)。

  1. 在將so推入陣列之前,我應該打電話給[so retain]嗎?
  2. load可能會失敗,如果有,則返回nil
    • 如果load沒有失敗,我必須從load返回之前調用[self release]
+6

是否有一個原因,你爲什麼選擇一個STL'矢量'超過'NSMutableArray'?本地Foundation類將爲您處理內存所有權。 –

+0

__Oh interesting__。我儘可能使用STL向量[出於性能原因](http://stackoverflow.com/a/4915303/111307)。我認識到我不會在C++容器中使用Objective-C對象獲得很大的性能收益,但是這個問題的目的是__理解Objective-C引用counting__。鑑於此,有人可以回答我在這裏發佈的兩個問題嗎? – bobobobo

回答

3

,但這個問題的目的是瞭解的Objective-C 引用計數

你要如果使用vector而不是使用NSArray瞭解可可的內存管理 。這是因爲遵循Cocoa內存管理規則的方法以一種很好的方式協同工作;但vector的方法不是用保留和發佈編寫的,因此不遵循可可手動引用計數規則。所以除非你使用ARC,否則你將不得不自行破壞內存管理規則,以明確地從外部對內存進行管理。這太可怕了,會教你錯誤的想法。

可可內存管理的好處在於它完全是本地的。你僅僅根據你在函數中做什麼來保留和釋放,而你從不需要擔心其他函數的作用。這就是靜態分析內存管理和實施ARC的可能性。

我的意思是? Cocoa內存管理的基本規則是,當一個函數被調用時,函數的對象參數保證有效(即不釋放),並且不能保證它隨時有效。而已。所以當你傳遞一個參數給另一個函數時,只要該對象在你傳遞它的時候是有效的,這就是你所需要擔心的。你永遠不需要「爲其他函數保留對象」,因爲其他函數無論如何都不能假定該對象在任何時候都是有效的。

這包括添加的東西到NSArray

Foo *obj = [[Foo alloc] init]; 
[myArray addObject:obj]; 
[obj release]; 

既然你不再增加之後需要obj,你可以自由地將其釋放。你不需要擔心其他事情。現在,正如其他人所說,這是有效的,因爲陣列保留了它的元素。 但你不需要知道這一點。 NSArray方法遵循與所有其他對象方法相同的規則。您不需要知道NSArray或任何其他類如何工作來執行內存管理權限。你甚至不需要知道什麼類型的對象是myArray或什麼addObject:。該方法負責處理它 - 如果需要將對象保留更長時間,它必須(作爲內存管理規則的一部分)以某種方式保留它;如果它不需要保留它,它不需要做任何事情。關鍵是,這對你無關緊要。

又如:

Foo *obj = [[Foo alloc] init]; 
[someObj performSelector:@selector(something:) withObject:obj afterDelay:5]; 
[obj release]; 

但這事異步的,所以我們怎麼能釋放呢?它的使用時間不會無效嗎?不,同樣,這一切都遵循相同的內存管理規則。您不必擔心該方法的作用。如果它需要以某種方式保持物體(並且在這種情況下),它必須保留它(並且確實如此)並且照顧釋放它等。

如果你試圖強制像vector這樣的圖片。你必須在放入東西之前保留東西,並在每次刪除元素時釋放東西。這很糟糕。你可以可以圍繞向量編寫一個包裝類,這樣你就可以擁有該文件中所有可怕的內存管理邏輯,而其他人可以將它用作普通的Objective-C類;但那樣會很像NSMutableArray

3

如果你正在編寫新的代碼,你應該只使用自動引用計數(ARC)。

它將緩解您遇到的很多潛在的內存問題。

此外,我會堅持與基金會收藏,如NSArrayNSMutableArray,而不是似乎是一個C++向量。

NSMutableArray *_myMutableArray = [[NSMutableArray alloc] init]; 

- (void)loadSound:(NSString *)name 
{ 
    SoundObject *so = [[SoundObject alloc] init]; 

    if(nil != so) 
    { 
    [so load:name]; 

    [_myMutableArray addObject:so]; 
    } 
} 
+0

對不起,我應該提到我不想在這裏使用'NSMutableArray' - 我想了解''[retain]'和'[release]'。 – bobobobo

+1

@bobobobo:好吧,不管你是否使用基金會收藏,你仍然可以使用ARC。它們不是相互排斥的。 – Josh

+0

我不使用ARC嗎?我以爲我是。 – bobobobo

相關問題