转载自:http://blog.sina.com.cn/s/blog_6dce99b10101jv12.html
序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。
到目前为止,看到oc实现的序列化方式有两种:NSKeyedArchiver,NSPropertyListSerializat
在这两种序列化方式中,NSData都是序列化的目标。两种方式的不同点在于NSPropertyListSerializat
首先讲NSPropertyListSerializat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
NSString * filepath = @”…”;
//omitted.
NSString * err;
//不需要初始化。如果有错误发生,会被复制。
NSDictionary * props = [NSDictionarydictionaryWithObjectsAnd
@
"Beijing,China”, @"
city”,
@
"supervior”,@"
position”,
@
"Qitiandasheng”,@"
company”,nil];
NSData * data = [NSPropertyListSerializat
format:NSPropertyListXMLFormat_v1_0
errorDescription:&err];
if
(!err){
[datawriteToFile:filePath atomically:YES];
//写入文件
}
else
{
NSLog(@
"errorwith:%@"
,err);
}
|
然后再来看NSKeyedArchiver。从基本的代码示例来看也很简单:
1
2
3
4
5
|
Person
"lucy"
];
lucy.address = @
"Beijing,China"
;
NSData * data = [NSKeyedArchiverarchiveDataWithRootObjec
[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进行封装