Objective-Cのゲッター、セッター (@propery, @synthesize)

前置き

どの言語でも、ゲッターとセッターを書くのって、
かったるいですよね。

そんなに情報隠蔽したいですかね。
ゲッター、セッターだけで何行書くんすかね。そんな世界でいいんですかね。
ということで、@propertyと@synthesizeの出番です。

前提知識を補充

@propertyと@synthesizeの前に、
Obj-Cのクラスの作り方を見てみておきましょう。

ヘッダー.h

@interface クラス名 : スーパークラス名
{
  インスタンス変数;
  インスタンス変数;
}
- メソッド;
- メソッド;

実装 .m

@implementation クラス名
- メソッド
- メソッド
@end

ヘッダー部と実装部がありますけど、今回まず注目したいのはヘッダー部の方。
再掲

@interface クラス名 : スーパークラス名
{
  インスタンス変数;
  インスタンス変数;
}
- メソッド;
- メソッド;

ゲッター、セッター作りたいときは、メソッドのところにゲッター、セッターを書くことになりますよね。

@interface クラス名 : スーパークラス名
{
  インスタンス変数;
  インスタンス変数;
}
- ゲッター;
- セッター;
- ゲッター;
- セッター;

たるい。

めんどくさいよー ありえないよー @propertyを使おう

@propertyを使えば、それはゲッターとセッターに置き換わります。
厳密には、ゲッターだけとかにできるみたいだけど、今回はそこは置いといて、
ゲッターとセッターの宣言に置き換わると覚えてしまおう。

@interface クラス名 : スーパークラス名
{
  インスタンス変数;
  インスタンス変数;
}
@property (nonatomic, retain) 型 変数名;
@property (nonatomic, retain) 型 変数名;

@propertyはゲッター、セッターに置き換わるので関数を宣言するところに書く。
なぜなら、ゲッター、セッターは関数だから。

おや、これってRubyの.....

これってRubyのattr_accessorなんじゃ

attr_accessor :変数名, :変数名

うん。そうだね。一緒だね。
いやちょっと待った。

実装.mをお忘れなく

Rubyはヘッダー.hとか実装.mの発想がないから
attr_accessorだけでいいのだけど、
Obj-Cはそうはいかない。
@propertyは宣言だけしかしてない。

@synthesizeを実装.mに書こう

@synthesizeは@implementationから@endまでのどこに書いてもよいみたい。

@implementation
@synthesize 変数名;
@synthesize 変数名;
@end

これで .(ドット)を用いてインスタンス変数にアクセス可能になる

Hoge *h = [Hoge alloc] init];
h.インスタンス変数 = @"AA";

みたいな感じで。

えぇ!!ゲッター、セッターができるって話であって、
どうしてドットが出てくるの!?と思うかもしれないが、
ドットがゲッター、セッターの役目をしてくれるみたい。



ちなみに、selfでもこのドットでアクセスしないと参照カウントの加算方法の問題でハマることがある......

@property (nonatomic, retain)のnonatomicとかretainって何?

nonatomicは複数のスレッドでは使わないよ。
retainは簡単に言うと参照カウントが1増える。
という意味だけど、厳密にはこんな短い文章で説明できるものではない。
retainが生成するコードは以下の参考書籍のP295に載っていました。

参考

詳解 Objective-C 2.0 改訂版

詳解 Objective-C 2.0 改訂版