如果对象是NSString、NSDictionary、NSArray、NSData、NSNumber等类型,可以直接用NSKeyedArchiver进行归档和恢复
不是所有的对象都可以直接用这种方法进行归档,只有遵守了NSCoding协议的对象才可以
NSCoding协议有2个方法:
encodeWithCoder:
每次归档对象时,都会调用这个方法。一般在这个方法里面指定如何归档对象中的每个实例变量,可以使用encodeObject:forKey:方法归档实例变量
initWithCoder:
每次从文件中恢复(解码)对象时,都会调用这个方法。一般在这个方法里面指定如何解码文件中的数据为对象的实例变量,可以使用decodeObject:forKey方法解码实例变量
一、标准的自定义对象归档写法
1.NSKeyedArchiver专门用来做自定义对象归档
什么时候调用:当一个对象要归档的时候就会调用这个方法归档
作用:告诉苹果当前对象中哪些属性需要归档
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_name forKey:@"name"];
[aCoder encodeInt:_age forKey:@"age"];
}
什么时候调用:当一个对象要解档的时候就会调用这个方法解档
作用:告诉苹果当前对象中哪些属性需要解档
initWithCoder什么时候调用:只要解析一个文件的时候就会调用
- (id)initWithCoder:(NSCoder *)aDecoder {
#warning [super initWithCoder]
if (self = [super init]) {
解档
注意一定要记得给成员属性赋值
_name = [aDecoder decodeObjectForKey:@"name"];
_age = [aDecoder decodeIntForKey:@"age"];
}
return self;
}
如果归档时需要归档的属性太多的话,写起来就比较麻烦了.
这种情况下可以使用 Runtime 实现, 就可以省下很多代码.
二、Runtime 实现自定义对象归档
//告诉系统要归档那些属性
- (void)encodeWithCoder:(NSCoder *)aCoder {
//利用runtime 归档
unsigned int count = 0;
Ivar *ivars = class_copyIvarList([Person class], &count);
for (int i = 0; i < count; i++) {
Ivar ivar = ivars[i];
const char *name = ivar_getName(ivar);
NSString *key = [NSString stringWithUTF8String:name];
//归档 KVC 根据一个 key 来获得一个值
[aCoder encodeObject:[self valueForKey:key] forKey:key];
}
//注意: C 语言里, 但凡出现 copy create new 就需要释放
free(ivars);
}
//告诉系统要解档那些属性
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
if (self = [super init]) {
//解档
unsigned int count = 0;
Ivar *ivars = class_copyIvarList([Person class], &count);
for (int i = 0; i < count; i++) {
Ivar ivar = ivars[i];
const char *name = ivar_getName(ivar);
NSString *key = [NSString stringWithUTF8String:name];
//解档
id value = [aDecoder decodeObjectForKey:key];
//KVC 设置值
[self setValue:value forKey:key];
}
free(ivars);
}
return self;
}
如果本文对你有所帮助, 请点心支持一下