2011-01-29 6 views
1

私はまだこれについて少し混乱しています。オブジェクトを解放する適切な時期はいつですか?

私はXcodeでオブジェクトをプログラムで作成していますが、UILabelもクラスワイドプロパティになります。

オブジェクトをリリースする適切な時期、作成されるメソッド、または通常のIBOutletオブジェクトのようなdeallocメソッドはいつですか?

ありがとうございました。

+2

いつ、それはあなたが知っているものの重要な部分を教えてくれたことを知っています。そして、現実世界はそれを残りのものに教えます。ドアを開けて、あなたのオブジェクトが自由に飛ぶようにしてください。 –

+0

正確には役に立たないが、非常にユーモラスな。ありがとう。 – thenameisnick

+0

私の人生の物語。 –

答えて

3

これはあなたの財産が値かどうかを保持するように設定されているかどうかによって異なります。通常は、プロパティが新しい値に設定されているときに、保持子(@synthesizeによって生成される)がretain/releaseを処理するようにします。あなたは、このような性質のように指定します。あなたは、デフォルトのゲッターとセッターを生成するために@synthesizeを使用することができます

@interface MyController : UIViewController { 
UILabel *myLabel; 
} 

@property (nonatomic, retain) UILabel *myLabel; 

@end 

MyController.h。 'retain'プロパティのデフォルトセッターは現在の値を解放し、新しい値を保持します。ただし、deallocでは何も実行されません。つまり、コントローラが破棄されると、リリースは呼び出されないため、あなたの参照はリークします。このような理由から、あなたはこのように、deallocを内のすべてのあなたの「保持」プロパティにreleaseを呼び出す必要があります。

MyController.m

@implementation MyController 

@synthesize myLabel; 

-(void) dealloc { 
self.myLabel = nil; 

[super dealloc]; 
} 

@end 

この場合には、self.myLabel = nilのほとんどであることに注意してくださいsetterが既存の値でreleaseを呼び出してから新しい値でretainを呼び出すため、[myLabel release]を呼び出すのと同じです。新しい値がnilなので、[nil retain]を呼び出すことは効果がありません。私はivarをnilに設定していて、ポインタがぶら下がっているのを避けるため、リリースする代わりにnilを使用する方が好きです。

このようなプロパティをインターフェイスビルダーからではなくプログラムで作成する場合は、IBOutletでマークする必要はありません。 IBを使用してコントロールを作成する場合は、すべてのIBOutlet参照をviewDidUnloadでゼロにする必要があります。これは、ビューが保持されていなければ、ビューと共にそのコントロールの割り当てを解除できるためです。

- (void)viewDidUnload { 
    [super viewDidUnload]; 
    // Release any retained subviews of the main view. 
    // e.g. self.myOutlet = nil; 

    self.myIBLabel = nil; 
} 

プロパティを使用すると、「自己」の部分を省略している場合に発生するもう一つのよくある間違い:それは彼らnilに良い練習ですので、後でそれを参照すると、このように、アプリがクラッシュします。 self.myIBLabel表記を使用しない場合は、getterとsetterをバイパスし、ivarを直接操作します。これはオブジェクトを保持/解放しません。

+0

+1良いもののために投げ込まれた細かい「細部」がたくさん書いてあります。ようこそ。 –

2

deallocメソッドで解放する必要がありますが、これはクラスプロパティの作成方法によって異なります。

あなたがそれを作成する方法でそれを解放し、それをクラスの他の部分で使用すると(これは、UILabelをクラスワイドのプロパティにしているので、私はあなただと思います)後でそれを変更しようとすると、不正なアクセス権が得られます。保持されているプロパティを使用している場合は、そのことを考慮する必要があります。ラベルを作成してクラスプロパティに割り当てると、ラベルが解放される可能性があります。

ここでは代表的な例です:

- (void) someMethod { 
    UILabel *myLabel = [[UILabel alloc] initWithFrame:myFrame]; 

    self.textLabel = myLabel; 
    [myLabel release]; 
} 


- (void) dealloc { 
    [textLabel release]; 
} 
+0

オブジェクトを割り当てたことがない場合(オートレリースされたオブジェクトを返す静的なファクトリメソッドを使用した場合)は、決して解放しないでください。 –

+1

これは本当です!私はそれを行う一つの方法しか示していない。 self.textLabel = [[[UILabel alloc] initWithFrame:myFrame] autorelease]のようなこともできます。これは、上で行ったことのすべてを無効にします。これは複数のアプローチがある場合の1つです。選択するのが最善です。この場合、Appleのメモリ管理文書は最も包括的なリファレンスであり、可能な場合はそれに頼るほうがはるかに優れています。 – lxt

関連する問題