02.实现NSCoding的自动归档和自动解档

需要自定义模型持久化的时候我们往往需要为各个模型实现对应的encode``decode方法

借助Runtime我们可以对此进行封装

解档

- (instancetype)initWithCoder:(NSCoder *)aDecoder{

    if (self = [super init]) {
        Class c = self.class;
        // 截取类和父类的成员变量
        while (c && c != [NSObject class]) {
            unsigned int count = 0;
            Ivar *ivars = class_copyIvarList(c, &count);
            for (int i = 0; i < count; i++) {
                NSString *key = [NSString stringWithUTF8String:ivar_getName(ivars[i])];
                id value = [aDecoder decodeObjectForKey:key];
                if (value){// 容错
                     [self setValue:value forKey:key];
                }
            }
            // 获得c的父类
            c = [c superclass];
            free(ivars);
        }
    }
    return self;
}

这里需要注意的是如果版本升级后Model的属性发生了变化这里可能会发生崩溃 所以需要在swtValueForKey的时候做判断

解档

- (void)encodeWithCoder:(NSCoder *)aCoder{

    Class c = self.class;
    // 截取类和父类的成员变量
    while (c && c != [NSObject class]) {
        unsigned int count = 0;
        Ivar *ivars = class_copyIvarList(c, &count);
        for (int i = 0; i < count; i++) {
            Ivar ivar = ivars[i];
            NSString *key = [NSString stringWithUTF8String:ivar_getName(ivar)];
            id value = [self valueForKey:key];
            if (value){
                 [aCoder encodeObject:value forKey:key];
             }
        }
        c = [c superclass];
        // 释放内存
        free(ivars);
    }
}

Last updated