2012-05-07 18 views
0

私はCのバックグラウンドから来ています。Objective-CはCから派生したものです。私はメモリ管理の概念が似ていると想定していました。潜在的なメモリリークについての警告が表示されていますが、奇妙なのは私がallocの後にオブジェクトを解放しているということです。この例を見てみましょう:iPhoneアプリのメモリリーク

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

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

答えて

1
  1. チェックプロパティcardCellArrayretaincopyある場合。もしそうなら、あなたがプロパティに設定され、あなたがself.cardCellArrayを呼び出している、オブジェクトはcardCellArrayがあるため、数1を保持してオブジェクトを返します(たとえば、initWithCapacity:など)alloc & initを使用してオブジェクトを作成する1.で

  2. をを増加保持を取得しますここでallocメソッドを呼び出しました。

    コールせずにオブジェクトを作成することがallocなど[NSMutableArray arrayWithCapacity:]としてautoreleaseオブジェクトを返しますが、あなたは、それが法deallocでのカウントに0

  3. を保持持っているあなたを考慮することができる(それはオートは、それが必要なときに1、カウントを保持だ低下します) [self.cardCellArray release]を呼び出すと、配列が保持するすべてのオブジェクトが自動的に削除されます。ここ

あなたのコード

[[NSMutableArray alloc] initWithCapacity:kTotalNumberOfCards]

後保持カウント-1のオブジェクトを生成し、あなたが

self.cardCellArray = xxx

呼び出すときに、このオブジェクトの保持カウントが2になりますしかしdeallocでは、cardCellArrayの保持カウントを減らさなかった鶏の漏れが発生しました。

だからあなたのコードが自動解放が自動的に必要なときに、カウントを保持減少します

self.cardCellArray = [[[NSMutableArray alloc] initWithCapacity:kTotalNumberOfCards] 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. 

最後に、右のdeallocメソッドでは、あまりにも

3

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

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

もう一つ:あなたの@property IVARのためにはどのように見えるかに応じて、self.cardCellArray =を使用している、あなたはそれがオブジェクトを保持してself.一部を除去する必要がある場合があります(または手動で、後でそれを解放する必要があります)。 @propertyはオブジェクトを保持していますcopyretain

+0

removeallobjectsをcardCellArrayを解放するために覚えていますか?私はちょうど例としてこれを使用していた、私は他の人の1つを投稿させて少しばかげている多くの他の人がいます – godzilla

+0

@ godzilla私の答えは – JustSid

+0

ああ、私は(nonatomic、保持)NSMutableArray * uncontrolledCards @ self.cardCellArray =私は実際に参照を渡さないでコピーしていますか? – godzilla

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命名されていることを前提としています。

1

はい、JustSidは、配列を2重に保持していて、それを解放しないことを示唆しています。

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

あなたはプロパティcardCellArrayが定義されているか言うことはありませんが、おそらくそれはあなたがself.cardCellArrayに割り当てるときに、あなたが本当に方法setCardCellArray、およびその方法を実行しているように、というオブジェクト「保持する」、retainedとして定義されています。しかし、あなたのallocコールの結果として既に保持されているので、今度は2回保持されます。

次に、deallocメソッドでは、releaseはまったくありません。 [cardCellArray release];を実行するか、self.cardCellArray = nil;を実行して、オブジェクトを解放することができます。いずれかがリリースされます(ただし、一度だけ - 二重保持で問題を解決する必要があります)。

あなたがいないが​​呼び出しを行う必要がありください。 releaseオブジェクト(および保持カウントがゼロになる)では、オブジェクトのdeallocメソッドが呼び出され、それが参照するオブジェクトに適したリリースが実行されます。

(とSIDが示唆するように、最後の[super dealloc]呼び出しを行う。)

(しかしもちろん、上記のすべては、あなたが物事の全く新しいと異なるセットを心配してもらうARC、と窓の外であるあなた台無しにすることができます。)

+0

お返事ありがとうございます、あなたは次のことについて助言してください:私はNSStringとプロパティを保持し、[self setFileName:[[NSString alloc] initWithFormat:@ "Pentagon.png"]];私はそれを2回割り振っていますか? – godzilla

+0

@godzilla - あなたは2度保持されます。 'alloc'は基本的にC言語の' malloc'に似ていますが、プリミティブオブジェクトヘッダのいくつかの追加設定を行い、その一部は保持カウントの増分をしています。 (Objective-Cに関する良い(または少なくともそうそう)の本を見つけて、ヒープ管理のことを調べる必要があります。これは簡単に "街中"でピックアップできるものではありません。 –

関連する問題