web-dev-qa-db-ja.com

Objective-C 101(保持vs割り当て)NSString

101の質問

私は車のデータベースを作成しており、各車オブジェクトは次のように定義されているとしましょう:

_#import <UIKit/UIKit.h>

@interface Car:NSObject{
    NSString *name;
}

@property(nonatomic, retain) NSString *name;
_

なぜ@property(nonatomic, retain) NSString *name;ではなく@property(nonatomic, assign) NSString *name;なのですか?

assignretainのように参照カウンターをインクリメントしないことを理解しています。しかし、なぜretainnametodoオブジェクトのメンバーであるため、そのスコープはそれ自体です。

他の外部関数もそれを変更しません。

54
qstar

Objective-Cには「オブジェクトのスコープ」のようなものはありません。スコープルールはオブジェクトのライフタイムとは関係ありません。保持カウントがすべてです。

通常、インスタンス変数の所有権を主張する必要があります。 Objective-Cのメモリ管理ルール を参照してください。 retainプロパティを使用すると、プロパティセッターは新しい値の所有権を主張し、古い値の所有権を放棄します。 assignプロパティを使用すると、周囲のコードでこれを実行する必要があります。これは、責任と懸念の分離という点で混乱します。 assignプロパティを使用する理由は、値を保持できない場合(BOOLやNSRectなどの非オブジェクト型など)、または保持するときに不要な副作用が発生する場合です。

ちなみに、NSStringの場合、正しい種類のプロパティは通常copyです。そうすれば、誰かがNSMutableStringを渡すと、あなたの下から変更できません(これは有効です— itisNSStringの一種です)。

68
Chuck

経由でアクセスすることを忘れないでください

self.name = something;

なぜなら

name = something;

生成されたセッター/ゲッターメソッドを気にしませんが、代わりに値を直接割り当てます。

19
Axel

retainがなければ、NSString*を設定しているnameは、割り当てステートメント自体よりも長く存続します。合成されたセッターにretainプロパティを使用することにより、メモリ管理システムに、NSString*周り。

12
fbrereto

self. in:

self.name = something;

は重要!これがないと、変数に直接アクセスし、セッターをバイパスします。

古いスタイル(間違っている場合は修正してください)は次のようになります。

[self setName:something];

とにかく、この表記は適切な@properties on NSStrings。アクセル、ありがとう。

9
jem

探している人のために、プロパティ属性に関するAppleのドキュメントは here です。

9
tbone

多くの記事を読んだ後、SO投稿し、可変プロパティ属性をチェックするデモアプリを作成し、すべての属性情報をまとめることにしました

  1. アトミック//デフォルト
  2. 非原子
  3. strong = retain // default
  4. weak = unsafe_unretained
  5. 保持する
  6. //デフォルトを割り当てる
  7. unsafe_unretained
  8. コピー
  9. 読み取り専用
  10. readwrite //デフォルト

そのため、上記のすべての属性を見つけることができる詳細な記事リンクがあります。ここで最高の回答をしてくれたすべての人に感謝します!!

iOSの可変プロパティ属性または修飾子

  1. retain = strong
    • 保持され、古い値が解放され、割り当てられます
    • retainは、新しい値を送信する必要があることを指定します-割り当て時に保持し、古い値を送信します-release
    • retainはstrongと同じです。
    • Appleは、「retain」と書くと、自動的に変換され、強いもののように動作するだけだと言います。
    • 「alloc」などのメソッドには、暗黙の「保持」が含まれます

例:

@property (nonatomic, retain) NSString *name;

@synthesize name;
  1. assign
    • assignはデフォルトで、単に変数の割り当てを実行します
    • assignは、プロパティのセッター実装を合成する方法をコンパイラに指示するプロパティ属性です
    • Cプリミティブプロパティにはassignを使用し、Objective-Cオブジェクトへの弱い参照にはweakを使用します。

例:

@property (nonatomic, assign) NSString *address;

@synthesize address;
8
swiftBoy

Googleの Objective-Cスタイルガイド は、これを非常によくカバーしています。

NSStringを取得するセッターは、受け入れる文字列を常にコピーする必要があります。単に文字列を保持しないでください。これにより、呼び出し元があなたの知らないうちに変更するのを防ぎます。 NSStringを受け入れているため、実際にはNSMutableStringではないことを想定しないでください。

3
funroll

クラスがこの文字列オブジェクトを取得し、その下から消えてしまった場合、それは残念でしょうか?クラスがそのオブジェクトについて2回目に言及したときのように、別のオブジェクトによって割り当て解除されましたか?

retainセッターセマンティクスを使用する理由です。

2
Dan Ray