0

私は C のバックグラウンドを持っていますが、Objective-C が C から派生したものであることはご存知のとおりです。メモリ管理の概念は似ていると思いました。メモリ リークの可能性に関する警告が表示されますが、奇妙なことに、alloc. 次の例を見てください。

self.cardCellArray = [[NSMutableArray alloc] initWithCapacity:kTotalNumberOfCards];

そしてdeallocで:

- (void) dealloc
{
[super dealloc];
[self.cardCellArray removeAllObjects];
}

私が得ているメモリリークメッセージは次のとおりです。

Method returns an Objective-C object with a +1 retain count

Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1

ここで私が間違っていることを誰かが見つけることができますか?

4

4 に答える 4

4

cardCellArray プロパティは所有参照 (保持またはコピー) であると想定しています。

self.cardCellArray = [[NSMutableArray alloc] initWithCapacity:kTotalNumberOfCards];

これは次のようになります。

self.cardCellArray = [[[NSMutableArray alloc] initWithCapacity:kTotalNumberOfCards] autorelease];

あるいは:

cardCellArray = [[NSMutableArray alloc] initWithCapacity:kTotalNumberOfCards];

メモリ管理が正しいことを確認します。

また、dealloc メソッドは次のようにする必要があります。

- (void)dealloc
{
   [cardCellArray release];
   [super dealloc];
}

これは、cardCellArray プロパティのインスタンス変数の名前が cardCellArray であることを前提としています。

于 2012-05-07T00:53:50.727 に答える
3

配列を解放するのではなく、単に空にするだけです。また、呼び出しを最後の行に移動したことにも注意してください[super dealloc]。これは、インスタンス変数を持つオブジェクトが、dealloc チェーンの後半で完全に解放され、解放されたメモリにアクセスしようとするためです。

- (void) dealloc
{
   [cardCellArray release];
   [super dealloc];
}

別のこと: を使用しself.cardCellArray =ています@propertyが、ivar の外観によってself.は、オブジェクトを保持しているため、パーツを削除する必要がある場合があります (または、後で手動で解放する必要があります)。@propertyオブジェクトを保持するcopyretain

于 2012-05-07T00:50:56.353 に答える
1

はい、JustSidが示唆しているように、アレイを二重に保持し、決して解放していません。

Objective-Cのヒープ管理はCにルーツがありますが、個々のオブジェクトの管理方法はまったく異なります。

cardCellArrayプロパティがどのように定義されているかはわかりませんが、おそらくretained、に割り当てたときにself.cardCellArray実際にメソッドを実行し、setCardCellArrayそのメソッドがオブジェクトを「保持」するように定義されています。allocただし、呼び出しの結果としてすでに保持されているため、 2回保持されるようになりました。

次に、このdealloc方法ではまったく行いませんrelease[cardCellArray release];を実行するか、を実行することにより、オブジェクトを解放できますself.cardCellArray = nil;。どちらかがそれを解放します(ただし、一度だけ-二重保持で問題を解決する必要があります)。

電話をかける必要はありませremoveAllObjectsreleaseオブジェクトを作成すると(そして保持カウントがゼロになると)、オブジェクトのdeallocメソッドが呼び出され、参照するオブジェクトに適したリリースが実行されます。

(そして、シドが示唆するように、[super dealloc]最後に電話をかけてください。)

(しかし、もちろん、上記のすべてはARCの窓の外にあります。そこでは、まったく新しい、異なる一連の問題について心配することになります。)

于 2012-05-07T01:16:49.397 に答える
1
  1. プロパティcardCellArrayretainまたはであるかどうかを確認しますcopy。その場合、 を呼び出しているときに、self.cardCellArrayプロパティcardCellArrayget に設定したオブジェクトの保持カウントが 1増加します。

  2. alloc& init( など)を使用してオブジェクトを作成するinitWithCapacity:と、保持カウント 1 のオブジェクトが返されます。これは、allocここでメソッドを呼び出しているためです。オブジェクトを返すなどの

    呼び出しなしでオブジェクトを作成している間(必要に応じて、保持カウントが1ずつ自動的に減少します)、保持カウントが0であると見なすことができます。alloc[NSMutableArray arrayWithCapacity:]autorelease

  3. メソッドdeallocでは、 を呼び出す必要があります[self.cardCellArray release]。これにより、配列が保持するすべてのオブジェクトが自動的に削除されます。

ここのコードは、後にretain-count-1オブジェクトを生成します

[[NSMutableArray alloc] initWithCapacity:kTotalNumberOfCards]

このオブジェクトの保持カウントは、呼び出すと 2 になります

self.cardCellArray = xxx

しかし、dealloc では cardCellArray の保持カウントを減らさなかったので、リークが発生しました。

コードを次のように変更します

self.cardCellArray = [[[NSMutableArray alloc] initWithCapacity:kTotalNumberOfCards] autorelease];

autorelease は、必要に応じて保持カウントを自動的に減らします。

またself.cardCellArray = [NSMutableArray arrayWithCapacity:kTotalNumberOfCards];

また

NSMutableArray *_array = [[NSMutableArray alloc] initWithCapacity:kTotalNumberOfCards];
self.cardCellArray = _array;
[_array release];

また

cardCellArray = [[NSMutableArray alloc] initWithCapacity:kTotalNumberOfCards];
//this helps because it doesn't call `[self setCardCellArray]` which generate +1 retain count.

最後に、cardCellArraydealloc メソッドでも解放することを忘れないでください

于 2012-05-07T02:26:02.833 に答える