现在的位置: 首页 > 综合 > 正文

objective-C中的序列化(serialize)与反序列化(deserialize)

2018年05月18日 ⁄ 综合 ⁄ 共 4215字 ⁄ 字号 评论关闭

转载自:http://www.cnblogs.com/yjmyzz/archive/2011/03/03/1969859.html

obj-c中有一类对象:NSArray,NSDictionary,NSString,NSNumber,NSDate,NSData以及它们的可变版本(指NSMutableArray,NSMutableDictionary...这一类) ,都可以方便的将自身的数据以某种格式(比如xml格式)序列化后保存成本地文件。



示例代码:NSArrayTest.h
1 #import
<Foundation/Foundation.h>
2 #define
FILE_NAME @"/tmp/data.txt"
3  
4 @interface NSArrayTest NSObject {
5 }
6  
7 -(void)
Test;
8  
9 @end
NSArrayTest.m
01 #import
"NSArrayTest.h"
02  
03 @implementation NSArrayTest
04  
05 -(void)
Test
06 {
07     NSArray *arr
= [
NSArray arrayWithObjects:@"one",@"two",@"three",nil];//注:最后一个要以nil结尾
08     [arr
writeToFile:FILE_NAME atomically:
YES];//(序列化为xml格式后)保存文件
09      
10     NSArray *arr2
= [
NSArray arrayWithContentsOfFile:FILE_NAME];//read
file
11     NSLog(@"%@",arr2);
12  
13 }
14  
15 @end
运行结果:
2011-03-03 14:20:01.501 pList[1246:a0f] (

    one,

    two,

    three

)
如果查看/tmp/data.txt,能看到下面的内容:
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE
plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3 <plist version="1.0">
4 <array>
5     <string>one</string>
6     <string>two</string>
7     <string>three</string>
8 </array>
9 </plist>

即NSArray默认是以xml格式来序列化对象的.

如果你用来存放数据的类是自己定义的,并不是上面这些预置的对象,那么就要借助正式协议NSCoding来实现序列化和反序列化。


比如,我们有一个自己的类Sample.h
01 #import
<Foundation/Foundation.h>
02  
03 @interface Sample
NSObject<NSCoding>
{
04  
05     NSString*
name;
06     int magicNumber;
07     float shoeSize;
08     NSMutableArray *subThingies;   
09 }
10  
11 @property(copyNSString*
name;
12 @property int magicNumber;
13 @property float shoeSize;
14 @property (retain) NSMutableArray *subThingies;
15  
16  
17 -(id)
initWithName:(
NSString *)n
magicNumber:(
int)m
shoeSize:(
float)
ss;
18  
19 @end
这里我们定义几个不同类型的属性,有字符串,有整数,有浮点数,还有一个可变长的数组对象
Sample.m
01 #import
"Sample.h"
02  
03 @implementation Sample
04  
05 @synthesize name;
06 @synthesize magicNumber;
07 @synthesize shoeSize;
08 @synthesize subThingies;
09  
10 -(id)
initWithName:(
NSString *)n
magicNumber:(
int)m
shoeSize:(
float)ss
11 {
12     if (self=[super init])
13     {
14         self.name
= n;
15         self.magicNumber
= m;
16         self.shoeSize
= ss;
17         self.subThingies
= [
NSMutableArray array];
18     }
19     return (self);
20 }
21  
22 -(void)
dealloc
23 {
24     [name
release];
25     [subThingies
release];
26     [super dealloc];
27 }
28  
29 //将对象编码(即:序列化)
30 -(void)
encodeWithCoder:(
NSCoder *)aCoder
31 {
32     [aCoder
encodeObject:name forKey:@
"name"];
33     [aCoder
encodeInt:magicNumber forKey:@
"magicNumber"];
34     [aCoder
encodeFloat:shoeSize forKey:@
"shoeSize"];
35     [aCoder
encodeObject:subThingies forKey:@
"subThingies"];
36 }
37  
38 //将对象解码(反序列化)
39 -(id)
initWithCoder:(
NSCoder *)aDecoder
40 {
41     if (self=[super init])
42     {
43         self.name
= [aDecoder decodeObjectForKey:@
"name"];
44         self.magicNumber
= [aDecoder decodeIntForKey:@
"magicNumber"];
45         self.shoeSize
= [aDecoder decodeFloatForKey:@
"shoeSize"];
46         self.subThingies
= [aDecoder decodeObjectForKey:@
"subThingies"];
47     }
48     return (self);
49      
50 }
51  
52  
53 -(NSString*)
description
54 {
55     NSString *description
= [
NSString stringWithFormat:@"%@:%d/%.1f
%@"
,name,magicNumber,shoeSize,subThingies];
56     return (description);
57 }
58  
59  
60 @end
注意其中的:encodeWithCoderinitWithCoder,这是NSCoding协议中定义的二个方法,用来实现对象的编码与解码。其实现也不复杂,利用的是key-value的经典哈希结构。当然一般在编码中,对于key的名字字符串,建议用define以常量方式事先定义好,以避免开发人员字符串键入错误。
测试一下:
01 #import
<Foundation/Foundation.h>
02 #import
"Sample.h"
03  
04 int main
(
int argc, const char *
argv[]) {
05     NSAutoreleasePool *
pool = [[
NSAutoreleasePool alloc]
init];   
06  
07     Sample
*s1 = [[Sample alloc] initWithName:@
"thing1" magicNumber:42
shoeSize:10.5]; 
08     [s1.subThingies
addObject:@
"1"];
09     [s1.subThingies
addObject:@
"2"];
10     NSLog(@"%@",s1);   
11     NSData  *data1
= [
NSKeyedArchiver archivedDataWithRootObject:s1];//将s1序列化后,保存到NSData中
12     [s1
release];
13     [data1
writeToFile:@
"/tmp/data.txt" atomically:YES];//持久化保存成物理文件
14              
15     NSData *data2
= [
NSData dataWithContentsOfFile:@"/tmp/data.txt"];//读取文件
16     Sample
*s2 = [
NSKeyedUnarchiver unarchiveObjectWithData:data2];//反序列化  
17     NSLog(@"%@",s2);
18       
19     [pool
drain];
20     return 0;
21 }

运行结果:

2011-03-03 14:36:48.540 pList[1322:a0f] thing1:42/10.5 (

    1,

    2

)

2011-03-03 14:36:48.548 pList[1322:a0f] thing1:42/10.5 (

    1,

    2

)

查看/tmp/data.txt,能看到以下内容:

由于经过了编码,里面的内容没有象前面的NSArray那样可读性强。

作者:菩提树下的杨过

出处:http://yjmyzz.cnblogs.com 

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

抱歉!评论已关闭.