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

系统 1561 0

转载自: 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 ( copy ) NSString * 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
注意其中的: encodeWithCoder initWithCoder ,这是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
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

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


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论