使用简单的数据存储有时候须要用到 NSCoding协议 实现其 encodeWithCoder 与 initWithCoder 方法代理
通常实现的姿式是这样的:code
可是这样会有一个缺陷, 若是咱们想加一个属性, 就要再在NSCoding代理方法里加入属性的序列化和反序列化操做, 不然会很容易致使项目崩溃, 那么有没有一种方式实现NSCOding协议而又不用再修改呢, 这时就须要用到强大的runtime了:blog
这样写的好处是无论有多少属性, 这两个方法都能经过runtime获取全部属性存取解决, 之后再添加任何属性都不用担忧NSCoding协议方法会有问题啦get
// copy代码请下拉:string
// 归档it
- (void)encodeWithCoder:(NSCoder *)aCoder {class
unsigned int count = 0;List
//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;
}