# 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);
    }
}
```
