在开发过程中,有时我们需要将自定义的一个数据模型进行存储,这时候可以选择归档的方式进行存储,在实现存储过程,需要遵守NSCoding协议,并且需要实现NSCoding的两个协议
- (void)encodeWithCoder:(NSCoder *)aCoder; /**< 归档操作 */
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder; /**< 解档操作 */
按照平常的方式我们需要每添加一个属性,在归档操作方法和解档操作方法中,都需要加入相对应的属性归档和解档操作
自定义了一个数据模型,有三个属性,进行归档存储
@interface MovieModel : NSObject <NSCoding>
@property (nonatomic, copy) NSString *title; /**< 电影名 */
@property (nonatomic, copy) NSMutableString *genres; /**< 电影种类 */
@property (nonatomic, copy) NSString *imagesUrl; /**< 电影图片 */
@end
实现N�SCoding的归档协议方法
/**
* 归档操作
*
* @param aCoder
*/
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_title forKey:@"title"];
[aCoder encodeObject:_imagesUrl forKey:@"imagesUrl"];
[aCoder encodeObject:_genres forKey:@"genres"];
}
再实现NSCoding的解档协议方法
/**
* 解档操作
*
* @param aDecoder
*
* @return
*/
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
if (self = [super init]) {
_title = [aDecoder decodeObjectForKey:@"title"];
_imagesUrl = [aDecoder decodeObjectForKey:@"imagesUrl"];
_genres = [aDecoder decodeObjectForKey:@"genres"];
}
return self;
}
其中,每个属性归档解档操作中的key都是唯一的,并且同一个属性的归档和解档操作对应的key必须要相同,如果数据模型的属性稍微多一点,工作量就有点繁琐,所以采取用runtime的反射机制来归档和解档操作比平常操作更方便和简洁
/**
* 归档
*
* @param aCoder
*/
- (void)encodeWithCoder:(NSCoder *)aCoder {
unsigned int count = 0;
// 利用runtime获取实例变量的列表
Ivar *ivars = class_copyIvarList([self class], &count);
for (int i = 0; i < count; i ++) {
// 取出i位置对应的实例变量
Ivar ivar = ivars[i];
// 查看实例变量的名字
const char *name = ivar_getName(ivar);
// C语言字符串转化为NSString
NSString *nameStr = [NSString stringWithCString:name encoding:NSUTF8StringEncoding];
// 利用KVC取出属性对应的值
id value = [self valueForKey:nameStr];
// 归档
[aCoder encodeObject:value forKey:nameStr];
}
// 记住C语言中copy出来的要进行释放
free(ivars);
}
/**
* 解档
*
* @param aDecoder
*
* @return
*/
- (id)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super init]) {
unsigned int count = 0;
Ivar *ivars = class_copyIvarList([self class], &count);
for (int i = 0; i < count; i ++) {
Ivar ivar = ivars[i];
const char *name = ivar_getName(ivar);
NSString *key = [NSString stringWithCString:name encoding:NSUTF8StringEncoding];
id value = [aDecoder decodeObjectForKey:key];
// 设置到成员变量身上
[self setValue:value forKey:key];
}
free(ivars);
}
return self;
}
这样子归档和解档操作就完成了,无论在数据模型中添加多少个属性,都不需要再进行归档和解档操作。
基本数据类型,不能使用NSUInteger