2012-01-06 6 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; 
} 

のように、2つのメソッドを持っているので、私の記憶管理-FUは、一種の弱いとして私と一緒にクマ。 releaseコマンドが呼び出されないので、リターン後に手動で作成された2つのディクショナリを解放することはできません。私は返品前にそれをすることはできませんまたは私は値を渡す。私の理解では、...

pool = [[NSAutoreleasePool alloc] init]; 

この自動解放プールにあるを処理する方法であり、そのような

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

としての私のオブジェクトを初期化してからならば、そう

[pool drain]; 

を呼び出しますそれは正しいです、どこで私はプールを初期化するのですか? awakeFromNibで?そして私は[プール排水]と呼ぶべきですか?

これが正しくない場合、誰かが私をまっすぐに(しかし、ゆっくりと入力してください)ことができます:あなたが返すオブジェクトをautoreleaseする必要があるD

おかげ

答えて

2

各スレッドには自動NSAutoreleasePoolがあり、新しいスレッドを作成する代わりにスレッドを作成する必要はありません。

[プールリリース]を使用してください。メモリリークが発生しない限り[プール排水]の代わりに

あなたのコードのためにそれはそうシステムはあなたのための自動解放プールを維持

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

感謝を。かなりそれぞれは、それぞれから何かを得ました。 – PruitIgoe

1

。呼び出しコードが使用するために存在しますが、後で任意の時点で解放されます。

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

    return [anotherDictionary autorelease]; 
} 

あなたは、オブジェクトの多くを生成するループを実行しながら、低メモリ使用量を確保するために必要としている場合を除き自動解放プールを使用する必要はほとんどないはずです。

この機能を実現するもう1つの方法は、便利なコンストラクタを使用してメモリを管理する必要がない自動解放オブジェクトを作成することです。例:

- (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に電話するだけでOKです。

P.S.あなた自身のオートリリースプールが必要な状況について知りたければ、Apple put together a nice guideあなたのために。

2

ほとんどの場合、自動解放プールが設定されています。 GCDを使用せずに別のスレッドでコードを実行している場合を除き、プールを割り当てて排水する必要はありません。あなたが同じメソッド内に流出しなければならないので、そのメソッドにautoreleaseプールを置いたとしても、オブジェクトはあまりにも早くオートレリースされます。オートレリースされたオブジェクトを取得すると、便利なコンストラクタを使用するか、にautoreleaseを追加することができます。あなたが後にリリースしたい

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

しかし私が言ったように、それは特別な場合の単なる選択肢です。

2

最高の解決策は、ARCを使用することです。それでは、これについてもう一度心配する必要はありません。 :)

でも、ARCがあなたに何をしているのかを理解する必要があります。私のiOSプログラミングの本の中での議論は、Mac OS Xにも同様に適用:すべての返信用

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