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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ryukiedev.gitbook.io/wiki/ios/runtime/runtime-shi-xian-nscoding-de-zi-dong-gui-dang-he-zi-dong-jie-dang.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
