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

转载自: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 @interfaceNSArrayTest:NSObject{
5 }
6
7 -(void) Test;
8
9 @end
NSArrayTest.m
01 #import "NSArrayTest.h"
02
03 @implementationNSArrayTest
04
05 -(void) Test
06 {
07 NSArray*arr = [NSArrayarrayWithObjects:@"one",@"two",@"three",nil];//注:最后一个要以nil结尾
08 [arr writeToFile:FILE_NAME atomically:YES];//(序列化为xml格式后)保存文件
09
10 NSArray*arr2 = [NSArrayarrayWithContentsOfFile: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 <?xmlversion="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 <plistversion="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 @interfaceSample :NSObject<NSCoding> {
04
05 NSString* name;
06 intmagicNumber;
07 floatshoeSize;
08 NSMutableArray*subThingies;
09 }
10
11 @property(copy)NSString* name;
12 @propertyintmagicNumber;
13 @propertyfloatshoeSize;
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 @implementationSample
04
05 @synthesizename;
06 @synthesizemagicNumber;
07 @synthesizeshoeSize;
08 @synthesizesubThingies;
09
10 -(id) initWithName:(NSString*)n magicNumber:(int)m shoeSize:(float)ss
11 {
12 if(self=[superinit])
13 {
14 self.name = n;
15 self.magicNumber = m;
16 self.shoeSize = ss;
17 self.subThingies = [NSMutableArrayarray];
18 }
19 return(self);
20 }
21
22 -(void) dealloc
23 {
24 [name release];
25 [subThingies release];
26 [superdealloc];
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=[superinit])
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 = [NSStringstringWithFormat:@"%@:%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 intmain (intargc,constchar* argv[]) {
05 NSAutoreleasePool* pool = [[NSAutoreleasePoolalloc] 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 = [NSKeyedArchiverarchivedDataWithRootObject:s1];//将s1序列化后,保存到NSData中
12 [s1 release];
13 [data1 writeToFile:@"/tmp/data.txt"atomically:YES];//持久化保存成物理文件
14
15 NSData*data2 = [NSDatadataWithContentsOfFile:@"/tmp/data.txt"];//读取文件
16 Sample *s2 = [NSKeyedUnarchiverunarchiveObjectWithData:data2];//反序列化
17 NSLog(@"%@",s2);
18
19 [pool drain];
20 return0;
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
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

你可能感兴趣的:(Objective-C)