2010-11-19 5 views
2

私はautoreleasepoolについて読んできましたが、私には少し不明な点があります。私は、autoreleasepoolを使って別々のメモリ管理が必要なスレッドを使っていくつかの機能を持っています。次の例ではiPhoneの自動回収プールと割り当て

が正しい

-(void) doSomething { 

    NSAutorelease *pool = [[NSAutorelasepool alloc] init]; 

    NSString *myString = @"Hello"; 

    [pool release]; 
} 

これは正しいですか?

またはこれですか?

-(void) doSomething { 

    NSAutorelease *pool = [[NSAutorelasepool alloc] init]; 

    NSString *myString = [[NSString alloc] initWithString:@"Hello"]; 

    [myString release]; 
    [pool release]; 
} 

私の質問は、自動解放プールのスコープで作成されたオブジェクトが、具体的relasedする必要があるかautorelasepoolがリリースされているときの世話をしている所有していますか?

あなたがごみにしたい 自動解放オブジェクトの束を作成しているときにのみ、独自の自動解放プールを作成する必要がありテオ

答えて

1

自動解放されたオブジェクトを自動解放プールが処理します。あなたがオブジェクトを所有している場合(allocまたはcopyまたはretainを介して)、それを解放する必要があります。したがって、2番目の例は正しくありません。あなたは文字列を割り当てたので、あなたはそれを所有しているので、それを解放しなければなりません。

メインスレッド用に自動解放プールが作成されます。 (あなたが望むなら、主な機能を見ることができます)。すべてのスレッドは、自動解放されたオブジェクトを管理するために独自の自動解放プールを必要とします。そのため、別のスレッドを作成する場合は、そのスレッドの自動解放プールを作成する必要があります。スレッド内に自動解放されたオブジェクトを作成しない場合でも、スレッドでライブラリ呼び出しが自動解放されたオブジェクトを作成できるように、これを作成する必要があります。ライブラリ呼び出しがオートレリースされたオブジェクトを作成していないと確信していても、それはベストプラクティスである必要があります。特に、複数の人が開発し管理する大きなプロジェクトに取り組んでいる場合に作成してください。

0

はすぐに集まります。ただし、プールを解放した後に作成する「オートレリース済み」オブジェクトは参照したくないという点では間違いありません。自動解放されたオブジェクト(保持していないオブジェクト)は、プールが空になったときに破棄されます。

例のオブジェクトはどれも自動リリースされていないので、独自の自動解放プールを作成することは基本的には何もしません。

+0

実際に彼はスレッドについて話しています。だから、オートリリースプールが必要です。 – taskinoor

+0

オートレリースされたオブジェクトを作成していない場合はどうすればよいですか? – zoul

+0

@zoul、私の答えの最後の部分を確認してください。あなたが同意しないかもしれませんが、私はベストプラクティスに従うことを好むでしょう。 – taskinoor

0

いずれの例も自動解放プールを必要としません。自動解放プールは、唯一の自動解放オブジェクトの世話をする:

NSArray *foo = [NSArray array]; 
NSObject *bar = [[[NSObject alloc] init] autorelease]; 

あなたの最初の文字列は、文字列リテラルを使用して初期化し、したがって、(多分他の誰かがより多くを知っている)は、おそらくメモリ管理に関して特別です。 2番目の文字列が漏れても、プールは違いはありません。 3番目の文字列が正しく解放されますが、プールは違いはありません。

あなたがプールを必要とするところである:

ここ
- (void) someMethodThatRunsOnAThread { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    NSString *foo = [@"foo" uppercaseString]; 
    [pool drain]; 
} 

プールがなかった場合foo文字列が漏れてしまいます。私はプールにreleaseの代わりにdrainを呼んでいることに注意してください.iOS上では違いはありませんが、ガベージコレクション環境では2つの違いがあるため、正しいものを呼び出す習慣に入る方が良いでしょう。

オブジェクトを自分自身で自動解放しない場合でも、プールが必要な場合があります。メソッドで呼び出しているコードのどこかで多くのメモリ操作が行われる可能性があります。

+0

実際に彼はスレッドについて話しています。私は例のメソッドが別のスレッドで実行されていると思います。 – taskinoor

+0

自動解放されたオブジェクトを作成していない場合は、スレッドに自動解放プールは必要ありません。 – zoul

+0

私の答えの最後の部分を確認してください。あなたが同意しないかもしれませんが、私はベストプラクティスに従うことを好むでしょう。 – taskinoor

0

がこのようなものであるべきだと思う:

-(void) doSomething { 

    NSAutorelease *pool = [[NSAutorelasepool alloc] init]; 


    NSString *myString = [[[NSString alloc] initWithString:@"Hello"] autorelease]; 

    // or create string like this (automatically autoreleased) 
    NSString *myString = [NSString stringWithString:@"Hello"]; 

    [pool release]; 
} 

あなたは自動解放プール内のオブジェクトに、自動解放メッセージを送信する必要があります。リリースメッセージがプールに送信されると、それらは解放されます。

+0

'-drain'と' -release'の両方を送ってプールを過剰にリリースしていませんか? – zoul

+0

おっと...はい... :) – marko

関連する問題