序列化 NSKeyedArchiver,NSPropertyListSerialization

转载自:http://blog.sina.com.cn/s/blog_6dce99b10101jv12.html


序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。



到目前为止,看到oc实现的序列化方式有两种:NSKeyedArchiver,NSPropertyListSerialization。

在这两种序列化方式中,NSData都是序列化的目标。两种方式的不同点在于NSPropertyListSerialization只是针对字典类型的,而NSKeyedArchiver是针对对象的。(补充一下,在Mac OS环境下,还可以使用NSArchiver获得更加精简的二进制序列化内容,但是NSArchiver在iOS环境下不支持)。

首先讲NSPropertyListSerialization,这个相对简单,只要创建一个NSDictionary,然后调用NSPropertyListSerialization dataFromPropertyList, 将内容写入NSData中就可以了。如果要读入,就调用propertyListFromData.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
NSString * filepath = @”…”; //omitted.
NSString * err; //不需要初始化。如果有错误发生,会被复制。
NSDictionary * props = [NSDictionarydictionaryWithObjectsAndKey:@”Lucy”, @"name”,
             @ "Beijing,China”, @" city”,
             @ "supervior”,@" position”,
             @ "Qitiandasheng”,@" company”,nil];
NSData * data = [NSPropertyListSerializationdataFromPropertyList:props
         format:NSPropertyListXMLFormat_v1_0
         errorDescription:&err];
if (!err){
     [datawriteToFile:filePath atomically:YES]; //写入文件
} else {
     NSLog(@ "errorwith:%@" ,err);
}

然后再来看NSKeyedArchiver。从基本的代码示例来看也很简单:

1
2
3
4
5
Person  * lucy  = [[Person alloc]initWithName:@ "lucy" ];
lucy.address = @ "Beijing,China" ;
 
NSData * data = [NSKeyedArchiverarchiveDataWithRootObject:lucy];
[data writeToFile:filePath];

 

这里要求Person类必须事先了NSCoding协议。NSCoding协议中包含两个必须事先的方法initWithCoder和encodeWithCoder. 参考下面这两个方法的实现:

1
2
3
4
5
6
7
8
9
-( void )encodeWithCoder:(NSCoder*)aCoder{
     [aCoderencodingObject:[NSNumber numberWithInt:self.age] forKey@ "age" ];
}
-(id)initWithCoder:(NSCoder*) aDecoder{
     if (self=[superinit]){
         self.age= ( int )[(NSNumber*)[aDecoderdecodeObjectForKey:@ "age" ]intValue];
     }
     return  self;
}

这里之所以用int age作为序列化属性的示例,是为了引出另一个话题,就是在序列化时对基础类型的处理。NSCoder中是不能存储基础类型的,包括int,float,char *什么的。要将这些进行序列化,必须要进行封装。

一般封装有两种方式。对于数值基本类型,使用Cocoa提供的封装,NSNumber就可以了。对于定长的struct,要分情况,如果struct的所有类型都是定长,并且成员中没有struct类型,那么可以直接使用NSValue来封装;否则,需要自己想办法进行key-value编写。char * 应该直接使用NSString进行封装


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值