使用简单的数据存储有时候需要用到 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;
}