归档在 IOS 中是另一种形式的序列化,只要遵循了 NSCoding 协议的对象都可以通过它实现序列化。由于决大多数支持存储数据的 Foundation 和 Cocoa Touch 类都遵循了 NSCoding 协议,因此,对于大多数类来说,归档相对而言还是比较容易实现的。
1.遵循 NSCoding 协议
NSCoding 协议声明了两个方法,这两个方法都是必须实现的。一个用来说明如何将对象编码到归档中,另一个说明如何进行解档来获取一个新对象。
新建一个类 Person,继承自 NSObject,设置属性和协议。并实现协议中的两个方法。
注意:如果需要归档的类是某个自定义类的子类时,就需要在归档和解档之前先实现父类的归档和解档方法。即 [super encodeWithCoder:aCoder] 和 [super initWithCoder:aDecoder] 方法;
2.使用
需要把对象归档是调用 NSKeyedArchiver 的工厂方法
archiveRootObject: toFile: 方法。
// 存储自定义对象使用归档
// 创建自定义对象
Person *p = [[Person alloc] init];
p.age = 24;
p.name = @"huangfei";
// 获取caches文件夹
NSString *cachesPath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];
// 拼接文件名
NSString *filePath = [cachesPath stringByAppendingPathComponent:@"person.data"]; // 后缀名随便写
// object:需要归档的对象
// file:文件的全路径
// 任何对象都可以进行归档
[NSKeyedArchiver archiveRootObject:p toFile:filePath];
// 调用自定义对象的 encodeWithCoder: ,否则会出错
// 如果一个自定义对象需要归档,必须遵守NSCoding协议,并且实现协议的方法
需要从文件中解档对象就调用NSKeyedUnarchiver的一个工厂方法 unarchiveObjectWithFile: 即可。
// 读取文件
// 获取caches文件夹
NSString *cachesPath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];
// 拼接文件名
NSString *filePath = [cachesPath stringByAppendingPathComponent:@"person.data"];
// 存进去是什么,读出来也是什么对象
// 解档
Person *p = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
// 底层会调用自定义对象的initWithCoder方法
NSLog(@"%@ %d",p.name,p.age);
3.几个要注意的地方
(1)如果对象是NSString、NSDictionary、NSArray、NSData、NSNumber 等类型,可以直接用 NSKeyedArchiver 进行归档和恢复。不是所有的对象都可以直接用这种方法进行归档,只有遵守了NSCoding协议的对象才可以;
(2)保存文件的扩展名可以任意指定;
(3)继承时必须先调用父类的归档解档方法。如果父类也遵守了 NSCoding 协议,应该在 encodeWithCoder: 方法中加上一句
[super encodeWithCode:encode];确保继承的实例变量也能被编码,即也能被归档。应该在 initWithCoder: 方法中加上一句
self = [super initWithCoder:decoder];确保继承的实例变量也能被解码,即也能被恢复。
最后,附上示例代码图片: