私の知る限り、XCode 4.4以降、@synthesize
はプロパティアクセサを自動生成するようになりました。しかし、今、私は NSUndoManager
に関するコードのサンプルを読みましたが、そのコードでは @synthesize
が明示的に追加されていることに気がつきました。みたいな感じです。
@interface RootViewController ()
@property (nonatomic, strong) NSDateFormatter *dateFormatter;
@property (nonatomic, strong) NSUndoManager *undoManager;
@end
@implementation RootViewController
//Must explicitly synthesize this
@synthesize undoManager;
今、戸惑いを感じています...。どのような場合に @synthesize
を明示的に追加すればよいのでしょうか?
明示的に @synthesize
を使用しない場合、コンパイラはそのプロパティを理解します。
@synthesize undoManager=_undoManager;
のように書くことができるようになります。
[_undoManager doSomething]; // iVar
[self.undoManager doSomethingElse]; // Use generated getter
これが一般的な慣例です。
と書くと
@synthesize undoManager;
を持つことになります。
[undoManager doSomething]; // iVar
[self.undoManager doSomethingElse]; // Use generated getter
個人的には、@synthesize
はもう必須ではありませんから、使うのをやめました。
私にとって @synthesize
を使う唯一の理由は、iVar
を @property
にリンクさせることです。もし、そのために特定のゲッターとセッターを生成したいのであれば。
しかし、与えられたコードには iVar
がないので、この @synthesize
は無駄だと思います。しかし、今、私は、新しい質問は、"いつ iVar
を使用するのですか "であり、私は、この質問に対して "never" 以外の回答はありません !
**When should I add @synthesize
explicitly to my code?
一般的には、それが必要な場合です。おそらく、それが必要なケースに遭遇することはないでしょう。
しかし、1つだけ便利なケースがあります。
例えば、カスタムゲッターとカスタムセッターの両方を書いていて、それをバックアップするインスタンス変数が欲しいとします。(アトミック・プロパティの場合、これはカスタム・セッターが欲しいのと同じくらい簡単です。コンパイラは単項プロパティのセッターを指定するとゲッターを書きますが、アトミック・プロパティの場合は書きません)。
これを考えてみましょう。
@interface MyObject:NSObject
@property (copy) NSString *title;
@end
@implementation MyObject
- (NSString *)title {
return _title;
}
- (void)setTitle:(NSString *)title {
_title = [title copy];
}
@end
これはうまくいきません。なぜなら _title
が存在しないのです。あなたはゲッターとセッターの両方を指定したので、Xcodeは(正しく)そのためのバッキングインスタンス変数を作成しないのです。
。
これを存在させるには、2つの選択肢があります。実装をこのように変更するか、
@implementation`をこのように変更するかです。
@implementation MyObject {
NSString *_title;
}
- (NSString *)title {
return _title;
}
- (void)setTitle:(NSString *)title {
_title = [title copy];
}
@end
または、このように変更します。
@implementation MyObject
@synthesize title = _title;
- (NSString *)title {
return _title;
}
- (void)setTitle:(NSString *)title {
_title = [title copy];
}
@end
つまり、synthesizeは実用上は決して必要ではありませんが、ゲッター/セッターを提供する際に、プロパティをバックアップするインスタンス変数を定義するために使用することができます*#39;。ここで、どちらの形式を使うかは、自分で決めることができます。
以前は、@implementation {}
でインスタンス変数を指定することを好んでいましたが、現在は、冗長な型を取り除き、バッキング変数をプロパティに明示的に結びつける @synthesize
ルートが良い選択だと考えています。
1.1.プロパティの型を変更すると、インスタンス変数の型も変更されます。
2.2. そのストレージ修飾子を変更する(例えば、strongの代わりにweakにしたり、 weakの代わりにstrongにする)、ストレージ修飾子が変更される。
3.3. プロパティを削除したり名前を変えたりすると、@synthesize
はコンパイラーエラーを発生させる。迷子のインスタンス変数ができることはありません。
*-複数のファイルにまたがる機能の分割に関連して、それが必要だったケースを1つ知っています。また、Appleがこれを修正しても、あるいはすでに修正していても、私は驚かないでしょう。
Xcode は明示的な @synthesize
宣言を要求しません。
もし、@synthesize
を書かなければ、それは.NET Frameworkを使うのと同じです。
@synthesize manager = _manager;
サンプルコードが古かったかもしれません。近いうちに更新されるでしょう。
のように、プロパティにアクセスすることができます。
[self.manager function];
これはAppleが推奨する規約です。私はそれに従っていますし、あなたもそうすることをお勧めします。