2009-09-07 17 views
8

私はしばらくの間、プロパティについて不思議に思っていました。プロパティを使用しているときに、リリースメッセージをオーバーライドして、プロパティがリリースされたプロパティであることを確認する必要がありますか?Objective-c 2.0のプロパティのメモリを解放する必要がありますか?

は、次の(架空の)例で十分ですか?

@interface MyList : NSObject { 
NSString* operation; 
NSString* link; 
} 
@property (retain) NSString* operation; 
@property (retain) NSString* link; 
@end 

@implementation MyList 
@synthesize operation,link; 
@end 
+1

NSStringはNSCopyingプロトコルを確認するので、 @property(copy、readwrite)NSString *操作 また、最新のランタイムを使用する場合は、インスタンス変数を指定する必要はありません。同様に合成された。 詳細については、Appleの「Objective-C 2.0プログラミングガイド」を検索し、「プロパティ宣言属性」および「プロパティ実装ディレクティブ」という節を探してください。 –

+0

+1素晴らしい質問がありました。同じことがまさに不思議でした。 – andy

答えて

13

のようなものを持っている必要があります。

- (void) dealloc { 
    [operation release]; 
    [link release]; 

    [super dealloc]; 
} 

別の方法:

- (void) dealloc { 
    self.operation = nil; 
    self.link = nil; 

    [super dealloc]; 
} 

好ましい方法ではありませんオブジェクトを解放することができますが、を合成したのバッキング変数を使用している場合は、それを実行する唯一の方法です。だから、

- (void) setLink:(MyClass *) value { 
    [value retain]; // calls [nil retain], which does nothing 
    [link release]; // releases the backing variable (ivar) 
    link = value; // sets the backing variable (ivar) to nil 
} 

注:この作品、なぜそれを明確にする、のがリンクプロパティのセッターの合成された実装を見てみましょう、と何それはゼロに設定されているときに起こりますネットの効果は、それがivarをリリースするということです。

+1

実際に合成されたイヴァールを使用している場合(つまり、対応するイヴァールは宣言していない場合)、ivarが生成されます。私の質問を参照してください:http://stackoverflow.com/questions/1283419 –

+3

一部のコンパイラはivarを合成しませんでした。これは、合成されたイヴァルをサポートした最初のコンパイラがリリースされた後に修正されました。したがって、混乱。 – bbum

+0

@bbumお知りになりたい!説明をいただきありがとうございます。 –

1

いいえ、-deallocメソッドを上書きします。そして、あなたがあなたの財産(またはむしろ背中の象牙)を解放しなければ、あなたは漏れるでしょう。だからここにあなたの@implementationであなたはあなたがいつものdeallocでのバッキング変数を解放する必要があり

- (void)dealloc { 
    [operation release]; 
    [link release]; 
    [super dealloc]; 
} 
3

非GCアプリケーションです。 ivarsを解放する代わりにnilを割り当てるのが普通です。 私の最高の経験は、initで初期化されたivarsをリリースし、保持モードとコピーモードでnilをプロパティに割り当てることです。唯一のgetterメソッドとsetterメソッドを作成し、プロパティの合成

- (void) dealloc { 
    self.operation = nil; 
    self.link = nil; 
    [super dealloc]; 
} 
+1

これは正しい方法です。 –

+1

@gsが正しくありません。 ivarを解放し、それらを直接nilに設定することができます。まれに、アクセサーを使用すると奇妙な副作用が生じることがあります。オブジェクトのプロパティを観測していて、オブジェクトがnilに設定されている場合、オブザーバはobjから他の情報を取得しようとするかもしれませんが、-deallocでset-to-nilが発生した場合、 –

+0

これは構文の奇抜です。合成されたまたは暗黙的な "@properties_release();"将来の言語仕様でdeallocメソッドに追加することができます。 Objective-C 2.0がすべての人にすべてのものになるならば、このアクセサー構文のようなものを推薦することは奇妙に思えます。そして、オブトラクターのオブザーバーとプロパティーアクセサーについて注意を払わなければなりません。 –

1

nilを

は、あなたのケースでは、私は割り当てます、そしてオブジェクトが割り当て解除されたときに、そのためには、IVARを解放しません。あなたは自分でivarをリリースする必要があります。

+1

これはデフォルトの(割り当て)属性を使用しない*宣言されたプロパティにのみ適用されます。アップルの「Objective-c 2.0 Programing Guide」を検索し、「宣言されたプロパティ」のセクション、特にdeallocに関する部分を読んでください。しかし、宣言されたプロパティは、あなたのdeallocメソッドの実装をクロスチェックする便利な方法を提供します:ヘッダーファイル内のすべてのプロパティ宣言を探し、assignとマークされていないオブジェクトプロパティが解放され、割り当てられたものはリリースされません。 –

2

これを行うための最善の方法は次のとおりです。

- (void)dealloc { 
    [operation release], operation = nil; 
    [link release], link = nil; 

    [super dealloc]; 
} 

実際に発生したセッターメソッド

self.operation = nil; 

を使用する方が便利だろうが、それが眉をひそめるされます。オブジェクトが割り当て解除されているスレッドを常に知っているとは限りません。したがって、アクセサを使用すると、KVO通知をトリガすることによって問題が発生する可能性があります。

ここでキャッチするのは、あなたのdeallocを@propertyで定義されたオブジェクト管理ポリシーと一致させる必要があるということです。例えば。 iVarを解放して(割り当て)プロパティを公開しないでください。

0

new、alloc、retainおよびcopyが表示されるたびに、pre-ARCがインスタンスvarまたはリリースする必要のあるプロパティであるかどうかを示します。強い変数を持つたびにARCでそれをnilに設定する必要があります。 どちらの場合でも、dealloc()をオーバーライドする必要があります。

関連する問題