什么是归档? 反归档?
把 OC 中基本数据存储到沙盒中,被称为基本数据持久化。 基本数据,在 oc中有以下四种,分别为 NSString 、 NSArray 、 NSDictionary 、 NSData。字符串、 数组、 字典 和 数据 这四种类型,系统提供了 writeToFile: 直接写入文件的方法, 因此可以直接存储数据到沙盒中。而对于 OC 中非基本数据类型,比如: UIImage 、 自定义类型Person 等,系统并没有提供 直接写入文件的方法。 这就需要我们把 非基本数据类型 转化为 NSData ,然后再存入到沙盒中。 把 复杂类型 通过 编码方式 转化为 data 型数据的过程称为,归档。 把 已编码的data 型数据, 通过解码方式转化为 原有复杂类型 的过程称为,反归档。
- (void)guidang
{
/**
归档(序列化):将遵守了NSCoding协议的对象转换成 NSData的过程
反归档(反序列化):将归档后的NSData数据转换回对象的过程
归档的流程:
step1:准备一个NSMutableData
step2:创建NSKeyedArchiver
step3:使用归档器 执行 encode编码
step4:归档器 finishEncode
*/
NSArray *arr = @[@"张三",@"李四",@"王五"];
User * user = [[User alloc]init];
user.name = @"我的";
user.age = @"20";
user.phone = @"13423";
/**
* @brief 先准备一块空白的可变data空间
*/
NSMutableData * data = [NSMutableData data];
/**
* @brief 创建归档对象时,指明归完档后的data要存在哪里
*/
NSKeyedArchiver * arch = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data];
[arch encodeObject:user forKey:@"user"];
[arch encodeObject:arr forKey:@"arr"];
/**
* @brief 注意:归档时一定要写以下这句才能真的归档
*/
[arch finishEncoding];
/**
* @brief 将归档完的data存到文件中
*/
NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *filePath = [NSString stringWithFormat:@"%@/test",[paths firstObject]];
[data writeToFile:filePath atomically:YES];
}
- (void)fanguidang
{
/**
step1:获取要反归档的NSData数据
step2:创建NSKeyedUnarchiver对象
step3:使用反归档器 执行decode解码
*/
NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *filePath = [NSString stringWithFormat:@"%@/test",[paths firstObject]];
NSData * data = [NSData dataWithContentsOfFile:filePath];
NSKeyedUnarchiver *unArch = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
User *user = [unArch decodeObjectForKey:@"user"];
NSArray * arr = [unArch decodeObjectForKey:@"arr"];
NSLog(@"%@",arr);
NSLog(@"%@",user.name);
NSLog(@"%@",user.age);
NSLog(@"%@",user.phone);
}
要归档的对象:
#import <Foundation/Foundation.h>
/**
* @brief 要进行归档,要服从协议
*/
@interface User : NSObject <NSCoding>
@property(nonatomic,copy)NSString * name;
@property(nonatomic,copy)NSString * age;
@property(nonatomic,copy)NSString * phone;
/**
* @brief NSCoding协议声明了两个方法
*/
/**
- (void)encodeWithCoder:(NSCoder *)aCoder; //将对象写入到文件中
- (id)initWithCoder:(NSCoder *)aDecoder; //将文件中的数据读入到对象中
*/
@end
#import "User.h"
@implementation User
/**
* @brief 当对一个对象进行归档时,自动调用该方法。
*/
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:_name forKey:@"name"];
[aCoder encodeObject:_age forKey:@"age"];
[aCoder encodeObject:_phone forKey:@"phone"];
}
/**
* @brief 当对一个对象进行反归档时,自动调用该方法。
*/
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super init];
if (self) {
self.name = [aDecoder decodeObjectForKey:@"name"];
self.age = [aDecoder decodeObjectForKey:@"age"];
self.phone = [aDecoder decodeObjectForKey:@"phone"];
}
return self;
}
@end