@dynamicを自前で実装する
こんにちは ビンゴ中西です。
Objective-Cのメタプログラミングを勉強中です。
Cora Dataを使っていると出てくる @dynamicこれは、
setterとgetterをどうやら実行時に作成するときに使われるみたい。
つまり、@dynamicはメタプログラミングでsetterとgetter作るよってことを示しているんですね。
やってみよう
Hoge.h
@property (nonatomic, retain) NSString *hoge;
Hoge.m
static Hoge* hogeSingle = nil; - (id)init { self = [super init]; if (self) { void (^setBlock)(id o, NSString *s) = ^(id o, NSString *s){ NSLog(@">>> %@",s); }; NSString *(^getBlock)(id o) = ^(id o){ NSLog(@"%@", o); return @"Test"; }; SEL setSel = NSSelectorFromString(@"setHoge:"); SEL getSel = NSSelectorFromString(@"hoge"); IMP setImp = imp_implementationWithBlock(setBlock); IMP getImp = imp_implementationWithBlock(getBlock); class_addMethod([Hoge class], setSel, setImp, "v@:@"); class_addMethod([Hoge class], getSel, getImp, "v@:"); } return self; } // シングルトン +(Hoge*)sharedManager{ @synchronized(self) { if (hogeSingle == nil) { hogeSingle = [[self alloc] init]; } } return hogeSingle; }
imp_implementationWithBlockの第1引数には呼び出しもとのインスタンスが入るみたいです。
Perlでのオブジェクト指向と一緒ですね。Perlも関数でオブジェクト指向をするために、第1引数に呼び出したインスタンスをもらってますし。
使い方
[[Hoge sharedManager] setHoge:@"AA"]; // sharedManagerでシングルトンをゲットしています。 NSLog(@"%@", [Hoge sharedManager].hoge);
結果:
>>> AA Test
それっぽく動いています。