2013年9月26日木曜日

NSCoding が捗るマクロ



こういうのを用意しておけば
#define OBJC_STRINGIFY(x) @#x
#define encodeObject(x) [aCoder encodeObject:x forKey:OBJC_STRINGIFY(x)]
#define decodeObject(x) x = [aDecoder decodeObjectForKey:OBJC_STRINGIFY(x)]

これが
- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super init];
    if(self) {
        _obj = [aDecoder decodeObjectForKey:@"_obj"];
    }
    return self;
}

- (void)encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeInt:_val forKey:@"_obj"];
}

こうなる
(id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super init];
    if(self) {
        decodeObject(_obj);
    }
    return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder
{
    encodeObject(_obj);
}


いつもコード書いてて気になってたところなので自分的にはかなりヒット。このマクロを使うメリットはキー値のタイプミスをコンパイラで拾うことができるところ。もちろんコード量も減る。(最初のケースだと一箇所間違えて @"_objj" と書いてもコンパイラはエラーは出さないし、実行時に意図通りに動かない)


仕組みは単純で # を使ってる。
Cでは #を使うとシンボルを文字列として扱うことができる。
#define STRINGIFY(x) #x
int myVariable = 5;
NSLog(@"%s", STRINGIFY(myVariable));
と書けば、"myVariable" がログに出る。

Obj-Cの文字列への変換もできて
#define OBJC_STRINGIFY(x) @#x
int myVariable = 5;
NSString *foo = OBJC_STRINGIFY(myVariable);
NSLog(@"%@", foo);
も "myVariable" がログに出る。

0 件のコメント:

コメントを投稿