[精通Objective-C]归档和序列化
参考书籍:《精通Objective-C》【美】 Keith Lee
使用Foundation框架的归档和序列化类可以将对象(对象图)转换为具有独立结构的字节缓冲区。这样就可以将数据写入文件或者传送给其他进程(通常会通过网络)。之后,这些数据可能会被转换回对象并保留相关的对象图。这些类为数据持久化提供了轻量级技巧。序列化处理类能够保存数据和对象在其层次结构中的位置,而归档处理类具有更广泛的用途,它们可以保存数据、数据类型和对象层次结构中对象之间的关系。
目录
归档
NSCoder是一个抽象类,声明了可用于对对象图进行序列化和反序列化的接口。序列化处理可以将对象的信息转换为字节序列,而反序列化处理可以通过字节序列(通过先前的序列化操作获得的)创建对象。
序列化归档
使用NSArchiver类和NSUnarchiver类可以创建序列化归档,这意味着序列化归档中的对象和值必须使用编码时使用的顺序才能解码。此外,在解码序列化归档时,必须解码整个对象图。使用NSArchiver类可以编码对象,以便将其写入文件或做其他用途,而使用NSUnarchiver类可以通过解码归档文件获得对象。
带键值的归档
NSKeyedArchiver类和NSKeyedUnarchiver类是带键值的归档类,即归档中的每个值都可以具有独有的名称和键值。这些键值必须在被编码和解码的对象内具有唯一性。
下面是带键值归档的使用:
// 使用NSKeyedArchiver类中的archiveRootObject:方法,将名为greeting的NSString实例归档到当前目录的greeting.archive文件中。
NSString *greeting = @"Hello,World!";
NSString *cwd = [[NSFileManager defaultManager] currentDirectoryPath];
NSString *archivePath = [cwd stringByAppendingString:@"/greeting.archive"];
BOOL result = [NSKeyedArchiver archiveRootObject:greeting toFile:archivePath];
if (result) {
// 使用NSKeyedUnarchiver类中的unarchiveObjectWithFile:方法对greeting.archive文件进行解码
NSString *greeting2 = [NSKeyedUnarchiver unarchiveObjectWithFile:archivePath];
NSLog(@"%@",greeting2);
}
编码和解码对象
当使用NSKeyedArchiver类和NSKeyedUnarchiver类执行归档过程时,必须使用遵守NSCoding协议的类。该协议声明了以下两个方法(具体使用会在后面给出):
-(id)initWithCoder:(NSCoder *)aDecoder;
-(void)encodeWithCoder:(NSCoder *)aCoder;
属性列表序列化
使用NSPropertyListSerialization类可以通过编程方式创建属性列表。该类支持以下数据结构:
NSData
NSDate
NSNumber
NSString
NSArray
NSDictionary
下面是一个属性列表序列化的例子,
其中format参数:
NSPropertyListOpenStepFormat // 传统的ASCII码属性列表格式
NSPropertyListXMLFormat_v1_0 // XML属性列表格式
NSPropertyListBinaryFormat_v1_0 // 二进制属性列表格式
options参数:
NSPropertyListImmutable // 返回的属性列表中含有不可变对象
NSPropertyListMutableContainers // 返回的属性列表中含有可变容器,但其中的元素不可变
NSPropertyListMutableContainersAndLeaves // 返回的属性列表中含有可变的容器和元素
// 序列化属性列表
NSError *errorStr;
NSDictionary *data = @{@"FirstName":@"John",@"LastName":@"Doe"};
NSData *plistData = [NSPropertyListSerialization dataWithPropertyList:data format:NSPropertyListXMLFormat_v1_0 options:0 error:&errorStr];
// 对属性列表进行反序列化