これらの宣言の違いは何ですか。それらを赤とオレンジと呼びましょう: 長所、短所?
2 に答える
赤いセットはプロパティで、オレンジのセットはインスタンス変数です。
プロパティ宣言は、getter メソッドと場合によっては setter メソッドを定義するようにコンパイラに指示します。(プロパティが読み取り専用の場合、setter メソッドはありません。)
Objective C の新しいバージョンでは、プロパティを宣言すると、プロパティの値を保存するために使用されるインスタンス変数も作成されます。慣例により、インスタンス変数はプロパティと同じ名前ですが、"_" プレフィックスが付いています。インスタンス変数の名前を変更する方法はありますが、今は無視しましょう。
プロパティ foo:
@property (nonatomic, strong) NSString *foo;
ゲッターメソッドがあります:
- (NSString *) foo;
とセッターメソッド
- (void) setFoo: (NSString *) foo;
これにより、次のようなコードを使用できます。
NSString *aString = self.foo;
また
NSString *aString = [self foo];
(ゲッターを呼び出す 2 つの異なる、等しく有効な方法)
そしてセッターを呼び出す
self.foo = @"a string";
また
[self setFoo: @"a string"];
(セッターを呼び出す 2 つの異なる、等しく有効な方法)
外部からクラスの値を取得および設定するパブリック インターフェイスを作成する場合、プロパティは非常に便利です。プロパティを「アトミック」として宣言すると、コンパイラは追加のコードをゲッターとセッターに追加するため、プロパティへの読み取りと書き込みは「スレッドセーフ」であり、バックグラウンド スレッドからアクセスできます。
ARC 以前は、プロパティは保持とリリースを管理するための非常にクリーンな方法でもありました。プロパティを「retain」として宣言し、セッターは渡されたオブジェクトを保持するように記述されています。システムが保持と解放を処理するため、ARC ではそれほど問題になりません。
コンパイラで作成されたコードの代わりに、独自のコードを呼び出すカスタム getter または setter メソッドを作成することもできます。これを使用して、情報をログに記録したり、変更に関する通知を送信したり、ラベルを更新したりできます。getter または setter と同じメソッド シグネチャを持つメソッド本体を .m ファイルに追加するだけで、コンパイラはそれを使用します。自動生成されたメソッドの代わりに。
前に言ったように、コードは次のとおりです。
self.foo = @"a string";
と同じです
[self setFoo: @"a string"];
そしてセッターメソッドを呼び出します。setter メソッドは、内部インスタンス変数 _foo を設定します。
ただし、コード
_foo = @"a string";
セッターを呼び出さずに、インスタンス変数を直接変更します。プロパティを定義する場合は、インスタンス変数の代わりに使用する必要があります。
Objective-C はシンプルで退屈なものでした。クラス (オレンジ色) のインスタンス変数を宣言し、(通常) それぞれに対して 2 つのメソッドを定義します。外部オブジェクトはそれを読み取ることができます。別名、ivar ごとにゲッターとセッターを作成する必要がありました。これは、インターフェースでは 2 行のコードであり、実装ファイルでは約 10 行のコードになることもありました。
次に、@property で宣言されたプロパティが続きました。通りでは多くの歓喜と飲酒がありました。これらの単一の @property 行は、正しいメモリ管理コードやミューテックス ロック コード (@property の宣言時に指定した内容に応じて) を含むこれらのメソッドを記述するようにコンパイラに指示します。
非常に多くの歴史がありますが、今日では、自動参照カウントにより、ivar を公開し、実装ファイルでプライベート ivar を宣言したい場合に、インターフェースで @properties を使用することだけが本当に意味があります。
最後に、@property はコンパイラに getter と setter を実装するように指示するだけでなく、同じ名前のインスタンス変数を自動的に提供しますが、アンダースコアが前に付けられます (これは、プロパティの暗黙的な合成が有効になっている場合のみです.. .more history)
だから、それが違いです。@property は、(本質的に) コードを記述するようにコンパイラに指示します。実際に記述するコードは、@property を宣言できるさまざまな方法によって変更されます。