1

私はこのようなコードを持っています:

vector<SoundObject*> sounds ;

- (void) loadSound:(NSString*) name
  {
    SoundObject* so = [[[SoundObject alloc] init] load:name] ;
    if( so )
      sounds.push_back( so ) ;
  }

さて、ここでいくつかのことを行いました(これは非常に初心者かもしれませんが、メモリリークに焦点を当てるだけです)。

  1. アレイ[so retain]にプッシュする前に呼び出す必要がありますか?so
  2. 失敗する可能性がloadあり、失敗した場合はを返しますnil
    • load失敗した場合、から戻る前に電話する必要がありますか?[self release]load
4

2 に答える 2

3

新しいコードを作成している場合は、自動参照カウント ( ARC ) を使用する必要があります。

これにより、発生する可能性のある多くの潜在的なメモリの問題が軽減されます。

さらに、 C++ のベクターのように見えるものではなく、NSArrayNSMutableArrayなどの Foundation コレクションに固執します。

NSMutableArray *_myMutableArray = [[NSMutableArray alloc] init];

- (void)loadSound:(NSString *)name
{
  SoundObject *so = [[SoundObject alloc] init];

  if( nil != so )
  {
    [so load:name];

    [_myMutableArray addObject:so];
  }
}
于 2012-09-08T03:10:03.877 に答える
3

しかし、この質問の目的は、Objective-C の参照カウントを理解することです

を使用するよりも使用すると、Cocoa のメモリ管理の理解が浅くなります。これは、Cocoa のメモリ管理規則に従うメソッドが適切に連携するためです。しかし、 のメソッドは保持と解放を使用して記述されていないため、Cocoa マニュアルの参照カウント規則に従っていません。したがって、ARC を使用していない限り、メモリ管理ルールを自分で破って、外部から明示的にメモリ管理する必要があります。これはひどいことであり、間違った考えを教えてしまいます。vectorNSArrayvector

Cocoa メモリ管理の優れた点は、完全にローカルであることです。関数内で何をするかに基づいてのみ保持および解放し、他の関数が何をするかについて心配する必要はありませんこれにより、メモリ管理を静的に分析し、ARC を実装することが可能になります。

どういう意味ですか?Cocoa メモリ管理の基本的なルールは、関数が呼び出されたときに関数のオブジェクト引数が有効である (つまり、割り当てが解除されない) ことが保証され、それ以降はいつでも有効であるという保証がないということです。それでおしまい。そのため、別の関数に引数を渡すときは、渡すときにオブジェクトが有効である限り、心配する必要があるのはそれだけです。とにかく、他の関数はオブジェクトがいつでも有効であると想定できないため、「他の関数のためにオブジェクトを保持する」必要はありません。

これには、次のものへの追加が含まれますNSArray

Foo *obj = [[Foo alloc] init];
[myArray addObject:obj];
[obj release];

追加したら不要objになるので、自由に解放してください。他のことを心配する必要はありません。さて、他の人が言ったように、これは配列がその要素を保持しているため機能します。しかし、あなたはそれを知る必要はありません。NSArray メソッドは、オブジェクトの他のすべてのメソッドと同じ規則に従います。メモリ管理を正しく行うために、NSArray やその他のクラスがどのように機能するかを知る必要はありません。myArrayオブジェクトの種類や機能を知る必要さえありませんaddObject:。そのメソッドはそれを処理します。オブジェクトをより長く保持する必要がある場合は、(メモリ管理規則の一部として) 何らかの方法でオブジェクトを保持する必要があります。保持する必要がない場合は、何もする必要はありません。重要なのは、それはあなたにとって重要ではないということです。

もう一つの例:

Foo *obj = [[Foo alloc] init];
[someObj performSelector:@selector(something:) withObject:obj afterDelay:5];
[obj release];

これは非同期処理を行うので、どうすれば解放できるでしょうか? 使用するまでに無効になることはありませんか?いいえ。繰り返しますが、これはすべて同じメモリ管理規則に従います。そのメソッドが何をするかについて心配する必要はありません。何らかの方法でオブジェクトを保持する必要がある場合 (この場合は保持する必要がある場合)、オブジェクトを保持する必要があり (実際に保持する必要があります)、解放などの処理を行う必要があります。

このようなシンプルさと美しさは、写真に無理やり押し込もうとすると消えてしまいますvector。要素を配置する前に保持し、要素が削除されるたびに解放する必要があります。ひどいです。vector の周りにラッパー クラスを記述して、そのファイルにひどいメモリ管理ロジックをすべて含めることができ、他のユーザーはそれを通常の Objective-C クラスとして使用できます。しかし、それはかなり似ていNSMutableArrayます。

于 2012-09-09T08:56:41.307 に答える