iOS 归档反归档的简单使用
2018-04-12 本文已影响33人
安静就好_
需要本地存储一些数据,NSUserDefaults支持的数据类型有:NSNumber(NSInteger、float、double),NSString,NSDate,NSArray,NSDictionary,BOOL.没有自定义的复杂对象,这个时候就需要归档反归档一下了。
1.从model下手,记得遵循NSCoding协议
@interface ZQWRenZhengFiveModel : NSObject<NSCoding>
/** 企业服务项目工作业绩id*/
@property(strong,nonatomic)NSString *objectId;
/** 服务师id*/
@property(strong,nonatomic)NSString *serverAttacheId;
/** 项目名称*/
@property(strong,nonatomic)NSString *name;
/** 项目承担单位名称*/
@property(strong,nonatomic)NSString *companyName;
/** 合同总额*/
@property(strong,nonatomic)NSString *rental;
/** 主要工作内容*/
@property(strong,nonatomic)NSString *jobContent;
/** 项目开始时间*/
@property(strong,nonatomic)NSString *startTime;
/** 项目结束时间*/
@property(strong,nonatomic)NSString *finishTime;
/** 完成情况*/
@property(strong,nonatomic)NSString *performance;
/** 备注*/
@property(strong,nonatomic)NSString *remark;
@end
.m文件 是不是很繁琐,runtime的用法下面介绍
-(void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeObject:_objectId forKey:@"objectId"];
[aCoder encodeObject:_serverAttacheId forKey:@"serverAttacheId"];
[aCoder encodeObject:_name forKey:@"name"];
[aCoder encodeObject:_companyName forKey:@"companyName"];
[aCoder encodeObject:_rental forKey:@"rental"];
[aCoder encodeObject:_jobContent forKey:@"jobContent"];
[aCoder encodeObject:_startTime forKey:@"startTime"];
[aCoder encodeObject:_finishTime forKey:@"finishTime"];
[aCoder encodeObject:_performance forKey:@"performance"];
[aCoder encodeObject:_remark forKey:@"remark"];
}
-(instancetype)initWithCoder:(NSCoder *)aDecoder{
if (self = [super init]) {
_objectId = [aDecoder decodeObjectForKey:@"objectId"];
_serverAttacheId = [aDecoder decodeObjectForKey:@"serverAttacheId"];
_name = [aDecoder decodeObjectForKey:@"name"];
_companyName = [aDecoder decodeObjectForKey:@"companyName"];
_rental = [aDecoder decodeObjectForKey:@"rental"];
_jobContent = [aDecoder decodeObjectForKey:@"jobContent"];
_startTime = [aDecoder decodeObjectForKey:@"startTime"];
_finishTime = [aDecoder decodeObjectForKey:@"finishTime"];
_performance = [aDecoder decodeObjectForKey:@"performance"];
_remark = [aDecoder decodeObjectForKey:@"remark"];
}
return self;
}
model搞定之后,就可以开始使用了
存储数据
在这里,我把所要存储的model放到数组,然后直接调用下面的方法就可以了
/**
归档数据
@param dataArr 存储的数组
*/
-(void)writeClick:(NSMutableArray *)dataArr{
NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)firstObject] stringByAppendingString:@"/ZQWRenZhengFive"];
NSMutableData *data = [NSMutableData data];
//创建归档对象
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[archiver encodeObject:dataArr forKey:@"ZQWRenZhengFive"];
[archiver finishEncoding];
BOOL result = [data writeToFile:path atomically:YES];
if (result) {
NSLog(@"写入成功 :%@",path);
// [[NSUserDefaults standardUserDefaults] setObject:@"ZQWRenZhengFive" forKey:@"ZQWRenZhengFive"];
}
}
去数据,反归档
//路径
NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)firstObject] stringByAppendingString:@"/ZQWRenZhengFive"];
//获取数据
NSData *myData = [NSData dataWithContentsOfFile:path];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:myData];
_dataArr = [unarchiver decodeObjectForKey:@"ZQWRenZhengFive"];
[unarchiver finishDecoding];
上边操作model着实有点费劲,下面用runtime来搞一搞
写一个NSObject的延展
.h文件
引入runtime的头文件
#import <objc/runtime.h>
添加两个方法
//忽略属性
- (NSArray *)ignoredNames;
- (void)decode:(NSCoder *)aDecoder ;
- (void)encode:(NSCoder *)aCoder;
.m 文件
- (void)decode:(NSCoder *)aDecoder {
// 一层层父类往上查找,对父类的属性执行归解档方法
Class c = self.class;
while (c &&c != [NSObject class]) {
unsigned int outCount = 0;
Ivar *ivars = class_copyIvarList(c, &outCount);
for (int i = 0; i < outCount; i++) {
Ivar ivar = ivars[i];
NSString *key = [NSString stringWithUTF8String:ivar_getName(ivar)];
// 如果有实现该方法再去调用
if ([self respondsToSelector:@selector(ignoredNames)]) {
if ([[self ignoredNames] containsObject:key]) continue;
}
id value = [aDecoder decodeObjectForKey:key];
[self setValue:value forKey:key];
}
free(ivars);
c = [c superclass];
}
}
- (void)encode:(NSCoder *)aCoder {
// 一层层父类往上查找,对父类的属性执行归解档方法
Class c = self.class;
while (c &&c != [NSObject class]) {
unsigned int outCount = 0;
Ivar *ivars = class_copyIvarList([self class], &outCount);
for (int i = 0; i < outCount; i++) {
Ivar ivar = ivars[i];
NSString *key = [NSString stringWithUTF8String:ivar_getName(ivar)];
// 如果有实现该方法再去调用
if ([self respondsToSelector:@selector(ignoredNames)]) {
if ([[self ignoredNames] containsObject:key]) continue;
}
id value = [self valueForKeyPath:key];
[aCoder encodeObject:value forKey:key];
}
free(ivars);
c = [c superclass];
}
}
nsobject的category写完之后,在model中使用
-(instancetype)initWithCoder:(NSCoder *)aDecoder{
if (self = [super init]) {
[ self decode:aDecoder];
}
-(void)encodeWithCoder:(NSCoder *)aCoder{
[self encode:aCoder]
}
//实现该方法选择要忽略的属性
- (NSArray *)ignoredNames {
return @[@"bone"];
}