を宣言する@property
と、コンパイラはアンダースコアで始まる変数、getter メソッド、setter メソッドを自動的に合成します。
@interface MyClass ()
@property(strong, nonatomic) NSString *myString;
@end
_myString
この例では、コンパイラは変数を として、ゲッターをとして syhtnesize します。
-(NSString *)myString
そしてセッターとして
-(void)setMyString:(NSString *)string
「@property」の後のキーワード(strong, nonatomic)
は、プロパティの属性を定義します。strong
デフォルトの は、所有権を意味します。つまり、この場合MyClass
、インスタンスは基本的にそれぞれmyString
のオブジェクトの保持/解放を担当します。nonatomic
たとえば、ゲッターがセッターと同時に呼び出された場合など、変数がマルチスレッド環境で常に有効な値であるとは限りません。
さらに、コンパイラは、インスタンス変数の取得/設定に使用されるドット構文を、適切な getter/setter メソッドの呼び出しとして扱います。したがって、与えられた MyClass のインスタンス
MyClass *exampleClass = [[MyClass alloc] init];
次のステートメントはどちらも同等です。
NSString *string1 = example.myString; // dot syntax
NSString *string1 = [example myString]; // explicit call to the getter method
さらに読むには、Apple のProgramming with Objective-C Guide を参照してください。
具体的な質問について:
1. 2 つのプロパティを作成できる場合、最初にそれらを宣言する意味はありますか?
実際には、変数をファイル内でパブリック変数として明示的に宣言することMyClass.h
はお勧めできません(または他のほとんどの場合)。代わりに、それらをプロパティとして宣言すると、プライベート変数 (およびアクセサー メソッド) が自動的に作成され、OOP のベスト プラクティスへの準拠が少し簡単になります。だから宣言する意味がない
// MyClass.h
@interface MyClass : NSObject {
NSString *myString // public variables not good
}
また、self.myString
ドット構文に関して上で述べたことにより、合成された変数の名前が.MyClass.m
instanceOfMyClass.myString
myString
_myString
2. それらに対応する 2 つのインスタンス変数とプロパティを作成するのはなぜですか?
上記を参照してください。インスタンス変数は 2 つ必要ではなく、1 つだけ必要です。
3. 代わりに、.m で変数を宣言して、クラスとそれをサブクラス化するすべてのものに対してプライベートに保つことができることを知っています。ここでの違いは何ですか?基本的なことがたくさん抜けているように感じます。これをすべて視野に入れる単純な方法はありますか?
@implementation
ファイルの一部で変数を非公開で宣言する.m
と、コンパイラは getter と setter を合成して支援することができなくなります。プライベート メソッドであっても、getter と setter はコードの複雑さを軽減するのに役立ちます。たとえば、変数値の有効性のチェックなどです。(注:アクセサー メソッドをオーバーライドできます。)
// MyClass.m
@interface MyClass () // private interface
@property(nonatomic, strong) NSString *myString;
@end
@implementation MyClass {
// no more need for private variables!
// compiler will synthesize NSString *_myString and accessors
}
-(void)setMyString:(NSString *)string { // overwrite setter
// no empty strings allowed in our object (for the sake of example)
NSAssert([string length] > 0, @"String must not be empty");
// assign private instance variable in setter
_myString = string;
}
@end
このように、 をサブクラス化する場合でもMyClass
、サブクラスは、コンパイラによって合成されたゲッター メソッドとセッター メソッドを継承します。