到目前为止,看到oc实现的序列化方式有两种:
NSKeyedArchiver,NSPropertyListSerializat
在这两种序列化方式中,NSData都是序列化的目标。两种方式的不同点在于NSPropertyListSerializat
propertyListFromData.
NSString * filepath = @”…”;//omitted.
NSString * err;//不需要初始化。如果有错误发生,会被复制。
NSDictionary * props = [NSDictionary dictionaryWithObjectsAndKey:@”Lucy”, @"name”, @"Beijing, China”, @"city”, @"supervior”, @"position”, @"Qitiandasheng”, @"company”, nil];
NSData * data = [NSPropertyListSerialization dataFromPropertyList:props format:NSPropertyListXMLFormat_v1_0 errorDescription:&err];
if(!err){
[data writeToFile:filePath atomically:YES];//写入文件
}else{
NSLog(@"error with:%@", err);
}
然后再来看NSKeyedArchiver。
从基本的代码示例来看也很简单:
Person * lucy = [[Person alloc] initWithName:@"lucy"];
lucy.address = @"Beijing, China";
NSData * data = [NSKeyedArchiverarchiveDataWithRootObjec
[data writeToFile:filePath];
这里要求Person类必须事先了NSCoding协议。
NSCoding协议中包含两个必须事先的方法initWithCoder和encodeWithCoder.
参考下面这两个方法的实现:
-(void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodingObject:[NSNumber numberWithInt:self.age] forKey @"age"];
}
-(id)initWithCoder:(NSCoder*) aDecoder{
if(self=[super init]){
self.age = (int)
[(NSNumber*)[aDecoder decodeObjectForKey:@"age"] intValue];
}
return self;
}
这里之所以用intage作为序列化属性的示例,是为了引出另一个话题,就是在序列化时对基础类型的处理。NSCoder中是不能存储基础类型的,包括int,float,char*什么的。要将这些进行序列化,必须要进行封装。一般封装有两种方式。对于数值基本类型,使用Cocoa提供的封装,NSNumber就可以了。对于定长的struct,要分情况,如果struct的所有类型都是定长,并且成员中没有struct类型,那么可以直接使用NSValue来封装;否则,需要自己想办法进行key-value编写。char* 应该直接使用NSString进行封装。