NSCoding协议

什么叫对象序列化?

对象序列化就是把对象写入到输出流中,用来存储或者传输,如果不序列化,(自定义对象是无法存储的)。
对象的反序列化就是从输入流中读取对象。
将对象转换为字节流保存起来,并在日后还原这个对象,这种机制叫做对象序列化。
我们可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间(注:要想将对象传输于网络必须进行流化!)

为什么要序列化?

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的典型例子。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容