簡體   English   中英

Objective-C:自動釋放混亂

[英]Objective-C: autorelease confusion

假設我有一個DoStuff類,該類​​有兩個方法,像這樣

- (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;  
}

好的,請耐心等待,因為我的記憶管理功能有點薄弱。 我不能釋放返回后手動創建的兩個字典,因為不會調用release命令。 在返回之前我無法做到這一點,或者我沒有傳遞任何值。 我的理解是使用自動釋放池來解決此問題的方法。

pool = [[NSAutoreleasePool alloc] init];

然后像這樣初始化我的對象

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

然后打電話

[pool drain];

所以,如果那是正確的,我應該在哪里初始化池? 在awakeFromNib中嗎? 我在哪里稱呼[水池排水口]?

如果這是不正確的,有人可以理順我(但請緩慢輸入):D

謝謝

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

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

對於您的代碼,釋放分配的對象是方法的責任,因此添加

 return [bundleOfJoy autorelease]; 
 return [anotherDictionary autorelease];

系統為您維護一個自動釋放池。 它是在程序啟動之前創建的,並在事件循環得到控制時定期清除。 在大多數情況下,您不需要自己的自動釋放池:只需在返回對象之前調用autorelease ,就可以了。

PS:如果您想了解確實需要自己的自動釋放池的情況, Apple可以為您提供一個不錯的指南

在大多數情況下,將為您設置自動釋放池。 除非您在不使用GCD的情況下在單獨的線程中運行代碼,否則不需要分配和消耗池。 即使您確實在該方法中放入了自動釋放池,該對象也會過早地自動釋放,因為您將不得不消耗相同的方法。 據說可以得到一個自動釋放的對象,您可以使用便捷構造函數或將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; 
}

而且您通常不會自己創建和消耗池,而是由框架為您完成的,因此您只需自動釋放要稍后釋放的對象即可。

當然,這種方式無法控制時間,因此,如果在程序的某些部分中創建了許多臨時自動釋放的對象,則可以將以下代碼包裝在池創建和消耗中:

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

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

最好的解決方案是使用ARC。 然后,您將不必再為此擔心。 :)

即使那樣,您仍需要了解ARC為您做了什么。 我的iOS編程書中的討論同樣適用於Mac OS X:

http://www.apeth.com/iOSBook/ch12.html#_memory_management

您需要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.
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM