2012-01-06 60 views
1

說我有一類DoStuff,那類有兩個方法,像這樣的Objective-C:自動釋放混亂

- (NSMutableDictionary* returnToCaller) methodOne : (NSString*) myString { 

    NSMutableDictionary* bundleOfJoy = [[NSMutableDictionary alloc] init]; 

    if (myString) { 
     bundleOfJoy = [self methodTwo]; 
    } 

    return bundleOfJoy; 

} 

- (NSMutableDictionary* returnToMethodOne) methodTwo { 

    NSMutableDictionary* anotherDictionary = [[NSMutableDictionary alloc] init]; 
    [anotherDictionary setObject: @"hardcodedstring" forKey: @"theKey"]; 

    return anotherDictionary; 
} 

好了,我承擔我的內存管理-FU是一種弱。我無法釋放在返回後手動創建的兩個字典,因爲釋放命令不會被調用。在退貨之前我無法做到或者我沒有任何價值。我的理解然後就是處理這是一個自動釋放池的方式......

pool = [[NSAutoreleasePool alloc] init]; 

和init我的對象這樣

NSMutableDictionary* anotherDictionary = [[[NSMutableDictionary alloc] init] autorelease]; 

,然後調用

[pool drain]; 

所以,如果這是正確的,我在哪裏啓動池?在awakeFromNib中?我在哪裏打電話[pool drain]?

,如果這是不正確可能有人理順我出去(但請慢慢鍵入):d

感謝

回答

2

在每個線程中都有一個自動NSAutoreleasePool,您不必創建一個,而是創建一個新線程。

使用[pool release];除非有內存泄漏,否則不要[pool drain]。

爲您的代碼是釋放分配對象的方法的職責,從而增加

return [bundleOfJoy autorelease]; 
return [anotherDictionary autorelease]; 
+0

感謝所有的答覆。每個人都有很多東西。 – PruitIgoe 2012-01-06 18:17:11

1

你需要autorelease您返回的對象。它們將存在於您的調用代碼中,但將在稍後的某個任意時刻發佈。

- (NSMutableDictionary* returnToMethodOne) methodTwo { 
    NSMutableDictionary* anotherDictionary = [[NSMutableDictionary alloc] init]; 
    [anotherDictionary setObject: @"hardcodedstring" forKey: @"theKey"]; 

    return [anotherDictionary autorelease]; 
} 

你應該幾乎從來沒有需要,除非你需要確保低內存佔用,同時運行產生大量的對象循環使用自動釋放池。

實現此功能的另一種方法是創建一個自動釋放對象,您不必管理內存(使用方便的構造函數)。例如:

- (NSMutableDictionary* returnToMethodOne) methodTwo { 
    NSMutableDictionary* anotherDictionary = [NSMutableDictionary dictionary]; // Creates an autoreleased NSMutableDictionary object. 
    [anotherDictionary setObject: @"hardcodedstring" forKey: @"theKey"]; 

    return anotherDictionary; // No `autorelease` call because it's not our memory to manage. 
} 
2

系統維護自動釋放池爲您服務。它在程序啓動之前創建,並在事件循環得到控制時定期排空。在大多數情況下,您不需要自己的自動釋放池:在返回對象之前只需撥打autorelease,即可。

P.S.如果您想了解有關您需要自己的自動釋放池的情況,請撥打Apple put together a nice guide

2

在大多數情況下,autorelease池已經爲您設置。除非您在不使用GCD的情況下在單獨的線程中運行代碼,否則不需要分配和排空池。即使您在該方法中放置了自動釋放池,該對象也會很快被自動釋放,因爲您必須在同一方法內耗盡。爲了獲得一個autoreleased對象,你可以使用一個方便的構造函數,或者將autorelease加到你的alloc/init

- (NSMutableDictionary* /*returnToMethodOne*/) methodTwo { 
    //Convenience constructor 
    NSMutableDictionary* anotherDictionary = [NSMutableDictionary dictionary]; 
    //or  
    //NSMutableDictionary* anotherDictionary = [[[NSMutableDictionary alloc] init] autorelease]; 
    [anotherDictionary setObject: @"hardcodedstring" forKey: @"theKey"]; 

    return anotherDictionary; 
} 
2

你通常不會造成瀝乾池自己,它是由你的框架做了,所以你才自動釋放對象要晚些時候公佈。

當然這樣你無法控制的時候,所以如果你在你的程序的某些部分產生大量的臨時自動釋放的對象,你可以用這段代碼在池中創建並漏:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
... create objects... 
[pool drain]; 

但正如我所說,這只是特殊情況下的一種選擇。