数据存储之归档
- 归档 NSKeyedArchiver : 序列化,把对象转为字节码,存储到文件中,然后将文件存储到硬盘中,实现数据的持久化
- 解归档 NSKeyedUnarchiver: 反序列化,把字节码转为对象
注:
1. 归档Foundation框架中的对象
2. 归档自定义的对象,但是需要注意所归档的对象类必须遵守协议
3. 归档之后的文件是加密的,安全性高
归档的代码实现
归档 (序列化)
归档的内容
NSArray *ary = @[@21, @"ios", @"apple", [NSDate date]];
归档的文件的路,即要存入的路径
NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSString *filePath = [documentPath stringByAppendingPathComponent:@"test.archiver"];
NSLog(@"%@",filePath);
归档
BOOL res = [NSKeyedArchiver archiveRootObject:ary toFile:filePath];
if (res) {
NSLog(@"归档成功");
}
解归档 (反序列化)
id object = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
NSLog(@"解归档: %@", object);
但是这种系统提供的归档方式太过死板,不够灵活,所以选择自定义归档方法
自定义归档方法实现
//归档文件的路径
NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *filePath = [documentPath stringByAppendingPathComponent:@"test.archiver"];
归档
1. 创建NSMutableData实例作为归档存储数据
NSMutableData *data = [NSMutableData data];
2. 创建归档的对象
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
3. 添加归档内容 (设置key、value值)
[archiver encodeObject:@"apple" forKey:@"name"];
[archiver encodeInt:21 forKey:@"age"];
[archiver encodeObject:@[@"abc",@"123"] forKey:@"ary"];
自定义的Student对象
Student *stu = [[Student alloc] init];
stu.name = @"jredu";
stu.num = 1;
[archiver encodeObject:stu forKey:@"stu"];
4. 完成归档
[archiver finishEncoding];
5. 将归档的数据存储到磁盘中
if ([data writeToFile:filePath atomically:YES]) {
NSLog(@"归档完成");
}
解归档
1. 从磁盘读取文件,生成NSData实例
NSData *contentData = [NSData dataWithContentsOfFile:filePath];
2. 根据NSData实例创建和初始化解归档的对象
NSKeyedUnarchiver *unArchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:contentData];
3. 解归档,根据key值获取value值
NSString *name = [unArchiver decodeObjectForKey:@"name"];
int age = [unArchiver decodeIntForKey:@"age"];
id ary = [unArchiver decodeObjectForKey:@"ary"];
NSLog(@"%@ %i %@",name, age, ary);
Student *unArchiverStu = [unArchiver decodeObjectForKey:@"stu"];
NSLog(@"name:%@ num:%i",unArchiverStu.name, unArchiverStu.num);
对于自定义的对象的归档,需要注意所归档的对象类必须遵守
#pragma mark - 编码:对对象的属性进行编码
-(void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeInt:_num forKey:@"num"];
[aCoder encodeObject:_name forKey:@"name"];
}
#pragma mark - 解码:解码归档数据初始化对象
-(id)initWithCoder:(NSCoder *)aDecoder{
if (self = [super init]) {
_num = [aDecoder decodeIntForKey:@"num"];
_name = [[aDecoder decodeObjectForKey:@"name"] copy];
}
return self;
}