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" |
4 | @interfaceNSArrayTest:NSObject{ |
NSArrayTest.m
01 | #import "NSArrayTest.h" |
03 | @implementationNSArrayTest |
07 | NSArray*arr = [NSArrayarrayWithObjects:@"one",@"two",@"three",nil]; |
08 | [arr writeToFile:FILE_NAME atomically:YES]; |
10 | NSArray*arr2 = [NSArrayarrayWithContentsOfFile:FILE_NAME]; |
运行结果:
2011-03-03 14:20:01.501 pList[1246:a0f] (
one,
two,
three
)
如果查看/tmp/data.txt,能看到下面的内容:
1 | <?xmlversion="1.0"encoding="UTF-8"?> |
即NSArray默认是以xml格式来序列化对象的.
如果你用来存放数据的类是自己定义的,并不是上面这些预置的对象,那么就要借助
正式协议NSCoding来实现序列化和反序列化。
比如,我们有一个自己的类Sample.h
01 | #import <Foundation/Foundation.h> |
03 | @interfaceSample :NSObject<NSCoding> { |
08 | NSMutableArray*subThingies; |
11 | @property(copy)NSString* name; |
12 | @propertyintmagicNumber; |
13 | @propertyfloatshoeSize; |
14 | @property(retain)NSMutableArray*subThingies; |
17 | -(id) initWithName:(NSString*)n magicNumber:(int)m shoeSize:(float) ss; |
这里我们定义几个不同类型的属性,有字符串,有整数,有浮点数,还有一个可变长的数组对象
Sample.m
06 | @synthesizemagicNumber; |
08 | @synthesizesubThingies; |
10 | -(id) initWithName:(NSString*)n magicNumber:(int)m shoeSize:(float)ss |
17 | self.subThingies = [NSMutableArrayarray]; |
25 | [subThingies release]; |
30 | -(void) encodeWithCoder:(NSCoder*)aCoder |
32 | [aCoder encodeObject:name forKey:@"name"]; |
33 | [aCoder encodeInt:magicNumber forKey:@"magicNumber"]; |
34 | [aCoder encodeFloat:shoeSize forKey:@"shoeSize"]; |
35 | [aCoder encodeObject:subThingies forKey:@"subThingies"]; |
39 | -(id) initWithCoder:(NSCoder*)aDecoder |
43 | self.name = [aDecoder decodeObjectForKey:@"name"]; |
44 | self.magicNumber = [aDecoder decodeIntForKey:@"magicNumber"]; |
45 | self.shoeSize = [aDecoder decodeFloatForKey:@"shoeSize"]; |
46 | self.subThingies = [aDecoder decodeObjectForKey:@"subThingies"]; |
53 | -(NSString*) description |
55 | NSString*description = [NSStringstringWithFormat:@"%@:%d/%.1f %@",name,magicNumber,shoeSize,subThingies]; |
注意其中的:
encodeWithCoder与
initWithCoder,这是NSCoding协议中定义的二个方法,用来实现对象的编码与解码。其实现也不复杂,利用的是key-value的经典哈希结构。当然一般在编码中,对于key的名字字符串,建议用define以常量方式事先定义好,以避免开发人员字符串键入错误。
测试一下:
01 | #import <Foundation/Foundation.h> |
04 | intmain (intargc,constchar* argv[]) { |
05 | NSAutoreleasePool* pool = [[NSAutoreleasePoolalloc] init]; |
07 | Sample *s1 = [[Sample alloc] initWithName:@"thing1"magicNumber:42 shoeSize:10.5]; |
08 | [s1.subThingies addObject:@"1"]; |
09 | [s1.subThingies addObject:@"2"]; |
11 | NSData*data1 = [NSKeyedArchiverarchivedDataWithRootObject:s1]; |
13 | [data1 writeToFile:@"/tmp/data.txt"atomically:YES]; |
15 | NSData*data2 = [NSDatadataWithContentsOfFile:@"/tmp/data.txt"]; |
16 | Sample *s2 = [NSKeyedUnarchiverunarchiveObjectWithData:data2]; |
运行结果:
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那样可读性强。