什么叫对象序列化?
对象序列化就是把对象写入到输出流中,用来存储或者传输,如果不序列化,(自定义对象是无法存储的)。
对象的反序列化就是从输入流中读取对象。
将对象转换为字节流保存起来,并在日后还原这个对象,这种机制叫做对象序列化。
我们可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间(注:要想将对象传输于网络必须进行流化!)
为什么要序列化?
1.需要将对象的状态保存到文件中,而后能够通过读入对象状态来重新构造对象,恢复程序状态
2.使用套接字在网络上传送对象的程序来说,是很有用的。
在对对象流进行读写操作时会引发一些问题,而序列化机制正是用来解决这些问题的!读写对象会有什么问题呢?其中一个最大的问题就是对象引用!举个例子来说:假如我有两个类,分别是A和B,B类中含有一个指向A类对象的引用,现在我们对两个类进行实例化{ A a = new A(); B b = new B(); },这时在内存中实际上分配了两个空间,一个存储对象a,一个存储对象b,接下来我们想将它们写入到磁盘的一个文件中去,就在写入文件时出现了问题!因为对象b包含对对象a的引用,所以系统会自动的将a的数据复制一份到b中,这样的话当我们从文件中恢复对象时(也就是重新加载到内存中)时,内存分配了三个空间,而对象a同时在内存中存在两份,如果我想修改对象a的数据的话,那不是还要搜索它的每一份拷贝来达到对象数据的一致性,这不是我们所希望的!
NSCoding首先是一个协议,类继承它,此类的实例才能被编码(encode)和译码(decode)。所有原生的类都是实现了NSCoding协议,在归档的过程中进行了转码,所以才可以归档成功。
NSCoding协议 API
NSCoding Protocol Reference
encodeWithCoder:
Encodes the receiver using a given archiver. (required)
- (void)encodeWithCoder:(NSCoder )encoder*
Parameters
<dl style="margin: 0px 24px 0.833em; padding: 0px; font-weight: 400; box-sizing: border-box; list-style: none;">
<dt style="margin: 0px 8px 8px; padding: 0px; font-weight: 700; box-sizing: border-box; list-style: none; clear: both;">encoder</dt>
<dd style="margin: 0.083em 0px 0.5em 1.25em; padding: 0px; font-weight: 400; box-sizing: border-box; list-style: none;">
An archiver object.
</dd>
</dl>
Availability
- Available in iOS 2.0 and later.
Declared In
NSObject.h
initWithCoder:
Returns an object initialized from data in a given unarchiver.(required)
- (id)initWithCoder:(NSCoder )decoder*
Parameters
<dl style="margin: 0px 24px 0.833em; padding: 0px; font-weight: 400; box-sizing: border-box; list-style: none;">
<dt style="margin: 0px 8px 8px; padding: 0px; font-weight: 700; box-sizing: border-box; list-style: none; clear: both;">decoder</dt>
<dd style="margin: 0.083em 0px 0.5em 1.25em; padding: 0px; font-weight: 400; box-sizing: border-box; list-style: none;">
An unarchiver object.
</dd>
</dl>
Return Value
self, initialized using the datain decoder.
Availability
- Available in iOS 2.0 and later.
Declared In
NSObject.h
NSCoding协议中只有两个方法,都是require的方法,一个是把本身的类进行转码,一个是逆转换成类对象,返回一个对象
示例
@interfaceStudent : NSObject<NSCoding>
@property (nonatomic, retain) NSString *name;
@property (nonatomic, retain) NSString *ID;
-(Student *)initWithName :(NSString*)newName
and : (NSString *)newID;
@end
@implementationStudent
@synthesize name = _name,ID = _ID;
//初始化学生类
-(Student *)initWithName:(NSString *)newName and:(NSString *)newID{
self = [super init];
if (self) {
self.name = newName;
self.ID= newID;
}
return self;
}
//学生类内部的两个属性变量分别转码
-(void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeObject:self.name forKey:@"name"];
[aCoder encodeObject:self.IDforKey:@"ID"];
}
//分别把两个属性变量根据关键字进行逆转码,最后返回一个Student类的对象
-(id)initWithCoder:(NSCoder *)aDecoder{
if (self = [super init]) {
self.name = [aDecoder decodeObjectForKey:@"name"];
self.ID= [aDecoder decodeObjectForKey:@"ID"];
}
return self;
}
@end
普及 :
数据存储中,Sqlite数据库的blob数据和NSData的兼容比较好,但是Sqlite不支持数组的直接存储。遵循NSCoding协议后,很轻易转化成nsdata。
blob:
BLOB (binary large object),二进制大对象,是一个可以存储二进制文件的容器。
在计算机中,BLOB常常是数据库中用来存储二进制文件的字段类型。
BLOB是一个大文件,典型的BLOB是一张图片或一个声音文件,由于它们的尺寸,必须使用特殊的方式来处理(例如:上传、下载或者存放到一个数据库)。
根据Eric Raymond的说法,处理BLOB的主要思想就是让文件处理器(如数据库管理器)不去理会文件是什么,而是关心如何去处理它。
但也有专家强调,这种处理大数据对象的方法是把双刃剑,它有可能引发一些问题,如存储的二进制文件过大,会使数据库的性能下降。在数据库中存放体积较大的多媒体对象就是应用程序处理BLOB的典型例子。