2009-11-02 5 views
13

私はNSStringのプロパティを宣言していますが、指定されたクラスとObjective-Cのはそれを文句はありません:

NSStringのNO「割り当て」、 'または 'コピー'属性が指定されている場合

その後、「代用が代わりに使用されている」ことがわかりやすくなります。

誰かが私にを割り当てるの違いを説明することができ、、通常のCのメモリ管理機能の面でコピーを保持しますか?

答えて

29

retainまたはcopyとは対照的に、assignが使用されているということに注意していると思います。 NSStringがオブジェクトであるため、参照カウント環境(つまりガベージコレクションなし)では、これは潜在的に「危険」である可能性があります(意図的に設計されている場合を除く)。次のように

はしかし、assignretaincopyとの違いは以下のとおりです。

  • を割り当てる:プロパティのためのあなたのセッターメソッドでは、新しい値にあなたのインスタンス変数の簡単な割り当てがあります例えば、

    これは、Objective-Cオブジェクトが参照カウントを使用するため問題を引き起こす可能性があるため、オブジェクトを保持しないとチャンスがありますあなたはまだそれを使用している間、文字列を割り当て解除することができます。

  • を保持:このはあなたのセッターメソッドで新しい値を保持します。たとえば:あなたは明示的にオブジェクトの参照を維持したいと述べている、それが割り当て解除される前に、あなたがそれを解放しなければならないので

    - (void)setString:(NSString*)newString 
    { 
        [newString retain]; 
        [string release]; 
        string = newString; 
    } 
    

    これは、より安全です。

  • コピー:これはあなたのセッターメソッドで文字列のコピーを作成します:

    - (void)setString:(NSString*)newString 
    { 
        if(string!=newString) 
        { 
         [string release]; 
         string = [newString copy]; 
        } 
    } 
    

    元のオブジェクトのコピーを作成すると、それは一方で変更されないことを保証しますので、これは、多くの場合、文字列で使用されていますあなたはそれを使用しています。

10

Cocoaは参照カウントを使用してメモリを管理します。参照カウントが0のオブジェクトは削除されます。

  • 割り当てが - 単に
  • が保持データへのあなたの変数を指す参照カウントする何もしません - あなたの変数がまだ生きている間、データへのあなたの変数をポイントし、参照カウントを1追加し、データはそこであることが保証され
  • コピーは - 、データのコピーを作成することで、あなたの変数を指すとApple独自のドキュメントを保持カウント1

もっと詳しくhereを、作ります。

+1

retain - __even if__ [deallocs]あなたが参照しているNSStringを保持しますか?または、同じインスタンスのすべてのユーザーが[リリース]する場合にのみ機能しますか? – bobobobo

+1

@bobobobo - 決して自分自身でdeallocを呼び出すべきではありません。常に 'release'や' autorelease'を使うべきです。 –

+0

デイブが言ったこと。あなたのデータが保証される理由は、誰もがリリースのみを使用していると仮定しているためです。他の人、またはあなた自身がdeallocを渡したり、オブジェクトを解放したりすると、そのデータは保証されません。 – bmalicoat

3

assign - 単純な割り当てを行うことでivarが設定されます。実装:

- (void) setFoo:(NSString *)newFoo { 
    foo = newFoo; 
} 

retain - IVARは、割り当てを行う前に保持して、メッセージを送っています。実装:

- (void) setFoo:(NSString *)newFoo { 
    if (foo != newFoo) { 
    [foo release]; 
    foo = [newFoo retain]; 
    } 
} 

- 割り当てを行う前にivarにコピーメッセージが送信されます。実装:

- (void) setFoo:(NSString *)newFoo { 
    if (foo != newFoo) { 
    [foo release]; 
    foo = [newFoo copy]; 
    } 
} 
+1

これはコンパイラが合成する実際の実装ではなく、(非GC)メモリ管理の観点からの動作を示します。 –

+0

@ニコライ - はい、ありがとうございます。 –