2

autoreleasepool について読んでいますが、少し不明な点があります。autoreleasepool を使用して個別のメモリ管理を必要とするスレッドを使用する機能がいくつかあります。

次の例では正しい

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

   [pool release];
}

またはこれ?

-(void) doSomething {

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

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

   [myString release];
   [pool release];
}

私の質問は、自動解放プールのスコープ内で作成された所有オブジェクトを明確に解放する必要があるか、または自動解放プールが解放されたときに処理されるかということです。

テオ

4

4 に答える 4

1

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

メインスレッド用に自動解放プールが作成されます。(必要に応じて、メイン関数を調べることができます)。すべてのスレッドには、自動解放されたオブジェクトを管理するための独自の自動解放プールが必要です。そのため、別のスレッドを作成する場合は、そのスレッドの自動解放プールを作成する必要があります。スレッドで自動解放されたオブジェクトを作成しない場合でも、そのスレッドでのライブラリ呼び出しが自動解放されたオブジェクトを作成する可能性があるため、これを作成する必要があります。自動解放されたオブジェクトを作成するライブラリ呼び出しがないと確信している場合でも、特に複数の人によって開発および保守される大きなプロジェクトに取り組んでいる場合は、自動解放オブジェクトを作成することをお勧めします。

于 2010-11-19T08:29:59.800 に答える
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];
}

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

于 2010-11-19T08:36:34.637 に答える
0

すぐにガベージ コレクションを行いたい一連の自動解放オブジェクトを作成する場合にのみ、独自の自動解放プールを作成する必要があります。ただし、プールを解放した後に作成した「自動解放された」オブジェクトを参照したくないという点では正しいです。自動解放されたオブジェクト (保持しないオブジェクト) は、プールが空になると破棄されます。

この例のオブジェクトはいずれも自動解放されないため、独自の自動解放プールを作成することは基本的にノーオペレーションです。

于 2010-11-19T08:28:41.923 に答える
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、プールが存在しない場合、文字列がリークします。drainプールではなく呼び出していることに注意してくださいrelease。iOS では違いはありませんが、ガベージ コレクション環境では 2 つが異なるため、適切な方を呼び出す習慣を身につけた方がよいでしょう。

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

于 2010-11-19T08:29:39.020 に答える