CoreData以外で@dynamicを使ってみた

CoreDataでNSManagedObjectのサブクラスを作ると必ず出てくる@dynamic. これ、CoreData以外の所で使ったこと無いなぁと思ったので、自分で全部実装して使ってみた。 なんの役に立つかは全くわからない・・・・・。

プログラムからメソッドを追加する

@dynamicが正常に動くためにはsetとgetの関数があればよい。なので、単純にsetとgetの関数をプログラム側から追加してあげればいいはず。 どうやってクラスにメソッドをプログラム側から追加できるのか調べてみたら、class_addMethodというのが出てきた。 これにクラス、メソッド名、c言語の関数、メソッドの形式を渡してあげれば動的に作れるらしい。 ということで作ってみたのがこれ。 setした値はインスタンス変数であるNSMutableDictionaryにいれている。

1
#import <objc/runtime.h> void setPropertyMethod(id self, SEL _cmd, id object){ NSString \*selectorString = NSStringFromSelector(_cmd); NSRange lengthRange = NSMakeRange(3, [selectorString length] - 4); NSString \*propertyName = [[selectorString substringWithRange:lengthRange] lowercaseString]; [self setValue:object forKey:propertyName]; } id getPropertyMethod(id self, SEL _cmd){ return [self valueForKey:[NSStringFromSelector(_cmd) lowercaseString]]; } @implementation dynamicClass -(void)addMethodToClass{ Class c = NSClassFromString(self.className); NSString \*propertyName = @"property"; NSString \*setSelector = [[NSString alloc] initWithFormat:@"set%@:",[propertyName capitalizedString]]; class_addMethod(c, NSSelectorFromString(setSelector), (IMP)setPropertyMethod, "v@:@"); class_addMethod(c, NSSelectorFromString(propertyName), (IMP)getPropertyMethod, "v@:"); } @end

地味にプロパティ名からsetのメソッド名を作るのに手間取ってるが、まぁどうせ使う用途も無いのでいいことにした。