こんにちは。きんくまです。
今回はObjective-Cの@propertyについてのまとめです。
ARCは使ってないバージョンです。
公式のリファレンスです。
>> Declared Properties
Obj-Cをはじめた当初はよくわからないながらも何となく使っていたのですが、
いろいろとわかってきたのでまとめておこうと思いました。
@propertyはカタカナに直すとプロパティだから、別言語から来た人(私)は
何か実体のあるもののような気がするのですが、そうではなくて
実際はアクセサメソッド(getter, setter)のことです。
なので、クラス外からアクセスするときに必要に応じて定義するとよいです。
最初私はよくわからず、インスタンス変数に全てプロパティを定義していたのはナイショです。
@propertyを使わないでインスタンス変数にアクセス = KVC
ではまずは@propertyを使わないでインスタンス変数にアクセスしてみましょう。
こんな感じのクラスがあるとします。
@interface Person : NSObject { NSString *_firstName; NSString *_lastName; int _age; } @end @implementation Person - (void)dealloc { [_firstName release]; [_lastName release]; [super dealloc]; } @end
これにアクセスするのに、Objective-Cに用意されている KVC(Key-value coding)という仕組みを利用します。
int main(int argc, const char * argv[]) { @autoreleasepool { Person *person1 = [[Person alloc] init]; [person1 setValue:@"Taro" forKey:@"_firstName"]; //KVC NSString *name1 = [person1 valueForKey:@"_firstName"]; //KVC NSLog(@"name1 = %@", name1); [person1 release]; } return 0; }
setValue:forKey で値代入(setter)。 valueForKey で値取得(getter)。することができます。
@propertyを定義
KVCでもアクセスできたのですが、毎回書くには長いです。
なので@propertyを使ってみます。その場合、定義する方は長くなるのですが、使う方は短くなります。
@interface Person : NSObject { NSString *_firstName; NSString *_lastName; int _age; } @property (nonatomic, retain) NSString *firstName; @property (nonatomic, retain) NSString *lastName; @property (nonatomic, assign) int age; @end @implementation Person @synthesize firstName = _firstName; @synthesize lastName = _lastName; @synthesize age = _age; - (void)dealloc { [_firstName release]; [_lastName release]; [super dealloc]; } @end
@interfaceのクラス定義のところで@propertyを書く。
@implementationのクラス実装のところで@synthesizeを書く。
というふうにやります。
@synthesize
実装ファイルのところで@synthesizeをこう書きました。
@synthesize firstName = _firstName;
私の場合はインスタンス変数とプロパティを明確に区別するために
・インスタンス変数は 「_」アンダースコアを変数名の最初につける
・プロパティには「_」をつけない
とそれぞれ別の名前で書いているので、プロパティとインスタンス変数をひもづけるために上の書き方になります。
もし、インスタンス変数とプロパティが同じ名前だったら
@synthesize firstName;
とするだけでよいです。
Attributes 属性
@propertyの後にあるnonatomic, retain, assignというのがあります。
これは補助情報というか属性というかそんなものです。
私の覚え方としてはこんな感じです。
Attributes | 説明 |
---|---|
nonatomic | スレッド使わないときはこっちを使う |
atomic | スレッド使うときはこっちを使う。(使ったことないです、、。) |
retain | setterのとき、代入する対象がNSObjectの子供だったらこっち |
assign | setterのとき、代入する対象がプリミティブ(int, float, charとかNSObjectの子供じゃない)だったらこっち |
readonly | 読み込み専用 |
@propertyを使ってアクセス
「.」ドット を使って書くことができます。KVCよりもすっきりかけました。
int main(int argc, const char * argv[]) { @autoreleasepool { Person *person1 = [[Person alloc] init]; person1.firstName = @"Taro"; person1.lastName = @"Yamada"; person1.age = 45; NSLog(@"%@ %@ is age %d", person1.firstName, person1.lastName, person1.age); [person1 release]; } return 0; }
@synthesizeの中身
@synthesizeは実際にどういうことをやるものなのかというと、
コンパイラが後から自動で実際のメソッドを付け足してくれるものです。
こちらで詳しい解説されてます。
>> Objective-Cの @property と @synthesize の組み合わせが何をやっているのかを解説 – 強火で進め
今回の場合だと実装部分にこんなのが足されます。
getterはプロパティと同じ名前の、setterは「set+プロパティ名」のメソッドになります。
- (NSString *)firstName { return _firstName; } - (void)setFirstName:(NSString *)firstName { [_firstName release]; _firstName = [firstName retain]; } - (NSString *)lastName { return _lastName; } - (void)setLastName:(NSString *)lastName { [_lastName release]; _lastName = [lastName retain]; } - (int)age { return _age; } - (void)setAge:(int)age { _age = age; }
@propertyはメソッドなので、必ずインスタンス変数に1対1対応していなくてもよい
@propertyはメソッドなので、必ずインスタンス変数に1対1対応していなくてもよいです。
例えば、今回の例に fullName をつけたしてみるとこうなります。
#import <Foundation/Foundation.h> @interface Person : NSObject { NSString *_firstName; NSString *_lastName; int _age; } @property (nonatomic, retain) NSString *firstName; @property (nonatomic, retain) NSString *lastName; @property (nonatomic, readonly) NSString *fullName; //追加 @property (nonatomic, assign) int age; @end @implementation Person @synthesize firstName = _firstName; @synthesize lastName = _lastName; @synthesize age = _age; @synthesize fullName; //追加 - (void)dealloc { [_firstName release]; [_lastName release]; [super dealloc]; } //追加 - (NSString *)fullName { return [NSString stringWithFormat:@"%@ %@", _firstName, _lastName]; } @end int main(int argc, const char * argv[]) { @autoreleasepool { Person *person1 = [[Person alloc] init]; person1.firstName = @"Taro"; person1.lastName = @"Yamada"; NSLog(@"fullName is %@", person1.fullName); //追加 [person1 release]; } return 0; }
■ 自作iPhoneアプリ 好評発売中!
・フォルメモ - シンプルなフォルダつきメモ帳
・ジッピー電卓 - 消費税や割引もサクサク計算!
■ LINEスタンプ作りました!
毎日使える。とぼけたウサギ