4

これが私が書いているいくつかのコードの要点です。NSMutableArrayの配列クラスメソッドの保持/解放の問題に適切に対処していないのではないかと心配しています。次は実際にメモリリークですか?

for(a while) { 
    // do stuff
    NSMutableArray *a = nil;
    // do stuff
    if (!a) {
        a = [NSMutableArray array];
    }
} // for(a while)
4

4 に答える 4

12

このコードでメモリをリークすることはありません。配列を自分で解放すると、実行ループの最後に配列が自動解放されたときにクラッシュが発生します。

ほとんどのCocoaクラスは、新しいオブジェクトを作成するためのいくつかの方法を提供し、この規則と非常に一貫しています。

  1. [[NSSomeObject alloc] init]:オブジェクトを解放するのはあなたの責任です(インスタンスメソッド)。

  2. [NSSomeObject someObject]:オブジェクトは、通常は実行ループ(クラスメソッド)の最後に自動解放されます。とほぼ同じ[[[NSSomeObject alloc] init] autorelease]です。

インスタンスメソッドの適切な使用法は次のとおりです。

a = [[NSMutableArray alloc] init];
// do stuff
[a release];

クラスメソッドの適切な使用法は次のとおりです。

a = [NSMutableArray array];
// do stuff, array is in the autorelease pool

Appleは、パフォーマンスを向上させるために、便利な方法からできるだけ離れることを推奨していることに注意してください。これは物議を醸すアドバイスであり、プロセッサ時間をあまり節約できない可能性があり、実際に保持することをあまり気にしない可能性のあるオブジェクトのリリースからalloc-initを分離します。

于 2009-06-13T16:25:00.373 に答える
6

Cocoa メモリ管理ルールから:

名前が「alloc」または「new」で始まるメソッド、または「copy」を含むメソッド (たとえば、alloc、newObject、または mutableCopy) を使用してオブジェクトを作成した場合、または保持メッセージを送信した場合、オブジェクトの所有権を取得します。release または autorelease を使用して、所有しているオブジェクトの所有権を放棄する責任があります。それ以外のオブジェクトを受け取った場合は、それを解放してはなりません。

したがって、次の行で:

a = [NSMutableArray array];

配列の所有権を取得せず、自動解放されて渡されます。メモリは自動解放プールによって自動的に処理され、使用されなくなると解放されます。ただし、配列を現在のイベントの外に保持したい場合は、それを保持する必要があります。そうしないと、配列が解放されます。

于 2009-06-13T16:01:34.627 に答える
2

はい、定着させたい場合は。

返されるオブジェクトは自動解放されたオブジェクトであり、その自動解放プールがパージされると割り当てが解除されます。

「array」で始まるすべての配列クラス メソッドは、これらのタイプの自動解放されたオブジェクトを返します。

Apple のこのドキュメントを読んでください。

于 2009-06-13T16:02:25.747 に答える
0

それは有効です。質問があるときは、手動で管理するだけで学習できる場合があります。

規則があります:

  • init プレフィックス (init、initWithString:) は保持カウント 1 を示します。
  • objectname プレフィックス (文字列、stringWithString:) は、自動解放されたオブジェクトを示します

私は何年もの間、自動的にリリースされるようにプッシュするのではなく、コール サイトでリリースできるものをリリースする習慣を持っていました。一部の自動解放の問題は、追跡が非常に困難になります。確かに、この場合、自動解放はプログラマーにとって便利ですが (何も問題がなければ)、再利用、明確さ、およびパフォーマンスに悪影響を及ぼします (大規模なコードベース/プログラムではなおさらです)。

于 2009-11-18T08:04:56.690 に答える