runtime序列化与反序列化

ε祈祈猫儿з 提交于 2019-12-04 12:39:02

使用简单的数据存储有时候需要用到 NSCoding协议 实现其 encodeWithCoder 与 initWithCoder 方法

一般实现的姿势是这样的:

 

但是这样会有一个缺陷, 如果我们想加一个属性, 就要再在NSCoding代理方法里加入属性的序列化和反序列化操作, 否则会很容易导致项目崩溃, 那么有没有一种方式实现NSCOding协议而又不用再修改呢, 这时就需要用到强大的runtime了:

这样写的好处是不管有多少属性, 这两个方法都能通过runtime获取所有属性存取解决, 以后再添加任何属性都不用担心NSCoding协议方法会有问题啦

// copy代码请下拉:

// 归档

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

    unsigned int count = 0;

    //1.取出所有的属性

    objc_property_t *propertes = class_copyPropertyList([self class], &count);

    //2.遍历的属性

    for (int i=0; i<count; i++) {

        //获取当前遍历的属性的名称

        const char *propertyName = property_getName(propertes[i]);

        NSString *name = [NSString stringWithUTF8String:propertyName];

        //利用KVC取出对应属性的值

        id value = [self valueForKey:name];

        //归档到文件中

        [aCoder encodeObject:value forKey:name];

    }

}

// 解档

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

    if (self = [super init]) {

        unsigned int count =0;

        //1.取出所有的属性

        objc_property_t *propertes = class_copyPropertyList([self class], &count);

        //2.遍历所有的属性

        for (int i = 0; i < count; i++) {

            //获取当前遍历到的属性名称

            const char *propertyName = property_getName(propertes[i]);

            NSString *name = [NSString stringWithUTF8String:propertyName];

            //解归档前遍历得到的属性的值

            id value = [aDecoder decodeObjectForKey:name];

            [self setValue:value forKey:name];

        }

    }

    return self;

}

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!