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;
なのですか?
assign
はretain
のように参照カウンターをインクリメントしないことを理解しています。しかし、なぜretain
はname
がtodo
オブジェクトのメンバーであるため、そのスコープはそれ自体です。
他の外部関数もそれを変更しません。
Objective-Cには「オブジェクトのスコープ」のようなものはありません。スコープルールはオブジェクトのライフタイムとは関係ありません。保持カウントがすべてです。
通常、インスタンス変数の所有権を主張する必要があります。 Objective-Cのメモリ管理ルール を参照してください。 retain
プロパティを使用すると、プロパティセッターは新しい値の所有権を主張し、古い値の所有権を放棄します。 assign
プロパティを使用すると、周囲のコードでこれを実行する必要があります。これは、責任と懸念の分離という点で混乱します。 assign
プロパティを使用する理由は、値を保持できない場合(BOOLやNSRectなどの非オブジェクト型など)、または保持するときに不要な副作用が発生する場合です。
ちなみに、NSStringの場合、正しい種類のプロパティは通常copy
です。そうすれば、誰かがNSMutableStringを渡すと、あなたの下から変更できません(これは有効です— itisNSStringの一種です)。
経由でアクセスすることを忘れないでください
self.name = something;
なぜなら
name = something;
生成されたセッター/ゲッターメソッドを気にしませんが、代わりに値を直接割り当てます。
retain
がなければ、NSString*
を設定しているname
は、割り当てステートメント自体よりも長く存続します。合成されたセッターにretain
プロパティを使用することにより、メモリ管理システムに、NSString*
周り。
self.
in:
self.name = something;
は重要!これがないと、変数に直接アクセスし、セッターをバイパスします。
古いスタイル(間違っている場合は修正してください)は次のようになります。
[self setName:something];
とにかく、この表記は適切な@properties
on NSStrings
。アクセル、ありがとう。
探している人のために、プロパティ属性に関するAppleのドキュメントは here です。
多くの記事を読んだ後、SO投稿し、可変プロパティ属性をチェックするデモアプリを作成し、すべての属性情報をまとめることにしました
そのため、上記のすべての属性を見つけることができる詳細な記事リンクがあります。ここで最高の回答をしてくれたすべての人に感謝します!!
例:
@property (nonatomic, retain) NSString *name;
@synthesize name;
例:
@property (nonatomic, assign) NSString *address;
@synthesize address;
Googleの Objective-Cスタイルガイド は、これを非常によくカバーしています。
NSStringを取得するセッターは、受け入れる文字列を常にコピーする必要があります。単に文字列を保持しないでください。これにより、呼び出し元があなたの知らないうちに変更するのを防ぎます。 NSStringを受け入れているため、実際にはNSMutableStringではないことを想定しないでください。
クラスがこの文字列オブジェクトを取得し、その下から消えてしまった場合、それは残念でしょうか?クラスがそのオブジェクトについて2回目に言及したときのように、別のオブジェクトによって割り当て解除されましたか?
retain
セッターセマンティクスを使用する理由です。