2012-01-21 12 views
1

オブジェクトの保持カウントがゼロになった場合にのみ、オブジェクトのdeallocが呼び出されることを読んだことがあります。iOSメモリリーク

私は、インターフェース部にUIColorのための一つのオブジェクトを取得し、プロパティ設定

UIColor *currentColor; 
@property (nonatomic, retain) UIColor *currentColor; 

実装セクションでは、このオブジェクトを使用した後、私はdealloc

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

におけるこのオブジェクトの解放メソッドを呼び出していています私は疑問に思っています。deallocは、このオブジェクトに対してどのように呼び出されますか?なぜなら、どこでも保持されているオブジェクトを解放しているわけではないからです。前もって感謝します。

答えて

2

を行うのに最適な場所である私は、オブジェクトのためにdeallocは、そのオブジェクトの保持 カウントがゼロになった場合にのみ、呼び出されることを読みました。

はい。

簡略化のため、currentColorオブジェクトを含むクラスをColorContainerと呼びます。さて、あなたは次のようなColorContainerのインスタンス作成する場合:containerColorため

ColorContainer* containerColor = [[ColorContainer alloc] init]; // retain count + 1 

保持カウントが1になります。

UIColorのインスタンスを作成し、そのインスタンスをcurrentColorプロパティに設定するとします。この場合、2通りの方法があります。 最初のインスタンスでは、次のようなインスタンスを作成できます。 initWithRed:green:blue:alpha:のようなインスタンスメソッドを使用する場合は、明示的にメモリを解放する必要があります。

UIColor color* = [[UIColor alloc] initWithRed:0 green:0 blue:0 alpha:1]; // retain count + 1 
containerColor.currentColor = color; // retain count +1, the referenced object has a retain count of 2 because you use a retain policy 
[color release]; // retain count -1, now the referenced object has a retain count of 1 

第2の方法では、代わりにクラスメソッド(+記号)を使用できます。この場合、そのクラスメソッドで作成されたオブジェクトは、アプリケーションの存続期間の特定の時点で自動解放されるため、メモリの抽象度を解放する必要はありません。

containerColor.currentColor = [UIColor whiteColor]; // retain count +1 

次に、containerColorオブジェクトをリリースするとします。 containerColorの保持カウントが1に等しい場合、それを使用するオブジェクトから解放すると、deallocメソッドを呼び出して、currentColorで参照されるオブジェクトも破棄することができます。あなたはこの

UIColor color* = [[UIColor alloc] initWithRed:0 green:0 blue:0 alpha:1]; // retain count + 1 
containerColor.currentColor = color; // retain count +1, the referenced object has a retain count of 2 
//[color release]; 
をすれば、それは、実際には1のカウントを保持している場合にのみ、あなたが currentColorが参照するオブジェクトが完全にメモリから削除されていることに注意する必要があり、この単純なケーススタディ(却下)で

あなたはメモリリークを作成します(理解しますか?)。あなたがretaincopyinitまたはnewを(それがalloc-initのと同じです)を使用する場合、あなたはそれらに対応releaseまたはautoreleaseを呼び出すために常に持って、要約する

メモリリークを避けるため、経験則として、オブジェクトの保持カウントのバランスを常に取る必要があります。

したがって、メタファとして、あなたは木のように思い出すことができます。親(containerColor)と子(currentColor)があるとします。親(1のカウントを保持する)が解放された場合、そのオブジェクトのdeallocメソッドと空きメモリが呼び出されます。 deallocメソッドで、(保持カウント1の)子を解放すると、deallocメソッドを呼び出してメモリを解放します。子の保持カウントが1より大きい場合、メモリリークが発生します。

希望します。

あなたがAbout Memory Managementを読むことができるさらなる情報について編集

。 iOS 5以降、AppleはARCを導入しています。 Automatic Reference CountingはObjective-Cオブジェクトの自動メモリ管理を提供するコンパイラです。情報については、Transitioning to ARC Release Notesを参照してください。

+0

Hello Flex、ありがとうございます。 – karthick

+0

あなたは大歓迎です! –

0

あなたは(alloccopyまたはretainを経由して)、それを割り当てられた場合にのみ、オブジェクトのreleaseを呼び出す必要があります。 retain属性を持つプロパティは、適切に処理する限り自動的にメモリ管理を行います。 self.currentColorでアクセスしてください。カラーオブジェクトの作成方法に応じて、releaseを使用する場合もありますが、の場合は常ににすると、deallocメソッドでプロパティをnilに設定する必要があります。二つの例:

  1. あなたのコードの問題は、あなたがreleaseautoreleaseを発行する必要があり、各alloccopyまたはretainの場合:

    // If you use this (or some other way to get the color without alloc, copy or retain) 
    // then you do not need to do any release 
    self.currentColor = UIColor.blackColor; 
    self.currentColor = [UIColor colorWithRed:1.0 green:0.5 blue:0.2 alpha:1.0]; 
    
    // On the other hand if you get it like this, you have to release/autorelease the object 
    self.currentColor = [[UIColor alloc] initWithRed:1.0 green:0.5 blue:0.2 alpha:1.0]; 
    [self.currentColor release]; 
    // or better 
    self.currentColor = [[[UIColor alloc] initWithRed:1.0 green:0.5 blue:0.2 alpha:1.0] autorelease]; 
    
    // dealloc always the same 
    -(void)dealloc{ 
        [currentColor release], currentColor = nil; 
        [super dealloc]; 
    } 
    

    ここでは2つの重要な事実があります。

  2. 割り当てを解除する場合を除き、常にself.currentColorを使用してプロパティにアクセスし、currentColorを使用しないでください。ここでは、self.currentColorを使用すると、システムによって自動的にメモリ管理コードが追加されます。 self.currentColorが設定されると、自動的にオブジェクトがretainreleaseになります。最終的な割り当て解除時にのみ、変数を直接設定する必要があります。詳しくはthis answer on the topic(Flex_Addictedのおかげ)を参照してください。

+0

deallocメソッドで 'self.currentColor = nil;'を呼び出すと、[release-or-set-nil-retained-members]で提案されているような問題が発生する可能性があります(http://stackoverflow.com/questions/5358134/release -or-set-to-nil-retained-members)と[MemoryMgmt Apple doc](http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html# // apple_ref/doc/uid/TP40004447-SW1) –

+0

ありがとう、かなり興味深い考え。私はそれに応じて私の投稿を編集します。 –

+0

あなたは大歓迎です。 –

2

あなたはあなたのcurrentColorプロパティのretainそのオブジェクトをセッターを保持し、あなたがそれを解放しなければならないオブジェクトのためのあなたretaincopyまたはallocメモリ場合に使用。 -(void)deallocはそれを

関連する問題