2009-05-09 10 views
2

私はこのように定義された@propertyを持っています:プロパティを解放する(Objective-C)

@property(nonatomic、retain)name;

関数では、いくつかのxmlを解析し、nameプロパティを設定します。 私は新しいインスタンスを保持する前に、以前の保持されたインスタンスを明示的に解放する必要がありますか? exempleについて

myObj.name = [otherObjのgetName]。 // ..カウント+1

保持

myObj.name = [otherObjのgetName]。 //名前の新しいインスタンスは、以前にリリースされた名前ですか?

答えて

4

、コードはこれとほぼ類似した何かを(我々はnameは、プロパティ名である必要があります、と_nameは、インスタンス変数になりますそれは参照しています):

- (void) setName: (NSString *) newValue 
{ 
    if (newValue == _name) 
    return; 

    [newValue retain]; 
    [_name release]; 
    _name = newValue; 
}

ここでは、上記のプロパティ宣言に基づいて何が起こるかを示しています。そのプロパティの他の可能な属性に応じて、その関数は[newValue retain]の代わりに[newValue retain]( 'copy'属性が指定された場合)のいずれかを使用するか、@synchronized(self)ブロックでラップされます( '非原子的'属性がが提供されます)。合成されたセッターを使用するようになります

@property (nonatomic, copy) NSString * name; 

:私はまた、つまり、あなたの財産は、NSCopyingプロトコルを実装NSStringの、を意味しているので、あなたが本当にコピーを使用してではなく、維持されなければならないことに注意しなければならない

-retainの代わりに-copyを使用します。これは、実際にNSMutableStringオブジェクトが渡されたときに安全です。不変の文字列は最終的には-copy呼び出しによって保持されますが、変更可能な文字列は新しい不変のコピーを作成します。そうしないと、文字列自体がセッターに渡された後に文字列自体が変更され、オブジェクトの知識なしに値が変更される可能性があります。

+0

NSMutableStringを変更できるようにしたい場合でも、新しい値に対してmutableCopyを実行する合成セッターをオーバーライドする必要があります。そうすれば、オリジナルは安全ですし、必要な場合は文字列のコピーを変更することができます。 – Abizern

+0

うん、あなたはNSMutableStringとしてあなたのプロパティを定義したいと思います。NSStringは 'クラスクラスタ'なので、NSString *サブクラス*のインスタンスを実際に取得することになるので、NSStringは実際には[str isKindOfClass: [NSMutableString class]]を使ってNSMutableStringかどうかをチェックすることはできません。NSMutableStringサブクラス。あなたの最善の策は、-mutableCopyを使用することです。受信者が既に変更可能な場合はそのまま残ります。 –

3

(ディレクティブを使用して)プロパティのアクセサーを合成した場合、プロパティが再割り当てされたときにそのプロパティをバッキングしているivarを解放します。明示的にivarをリリースしたいときは、オブジェクトが割り当て解除されるときだけです。だから、あなたのdeallocメソッドは次のようになります。合成されたプロパティのセッターで

- (void)dealloc { 
    [name release]; 
    // other cleanup here 
    [super dealloc]; 
} 
+0

基本的に、プロパティはgetterとsetterを呼び出すための略語です。プロパティを設定すると、セッターに何が起こっても起こります。合成プロパティの保持とコピーのプロパティでは、古いオブジェクトを解放し、新しいオブジェクトを保持(またはコピー)します。 – Chuck

+0

@chuckはい、私は知っています。それは、プロパティが合成されている限り、プロパティが管理されるように指定した理由です。 –

関連する問題