类的序列化和反序列化、对象的归档个解档

对象的编码把对象的类特征以及对象状态转化为某种格式(二进制),这种格式可以存储,也可以在进程间和网络间传递。

类的类型以及实例数据会被写入到某种字节流中,当程序结束的时候,该字节流可以进行持久化。程序启动的时候,新分配的对象可以解码之前保存的自身描述,然后把自己恢复到之前运行时的状态。编码通常需要和归档协作。归档将对象转化成一种可以写进文件系统的格式(档案)。解档则是在档案上执行操作。在此过程中,保存在档案的对象需要对自身进行解码。

所以,如果需要将某种类型的实例对象进行归结档,则首先需要对该类进行序列化和方序列化(编解码),该类需遵循NSCoding协议。

1.序列化和反序列化

协议中有两个Required方法:

1 - (void)encodeWithCoder:(NSCoder *)aCoder;//序列化数据,保存到acoder中
2 - (id)initWithCoder:(NSCoder *)aDecoder;//从aDecoder读取数据,保存到对应的变量中,反序列化数据

而NSCoder则时一个抽象类,需要在其子类中实现。它的定义如下:

@interface NSCoder : NSObject
- (void)encodeValueOfObjCType:(const char *)type at:(const void *)addr;
- (void)encodeDataObject:(NSData *)data;
- (void)decodeValueOfObjCType:(const char *)type at:(void *)data;
- (NSData *)decodeDataObject;
- (NSInteger)versionForClassName:(NSString *)className;
@end

2.归结档:有两种方式可以进行归结档操作。

键--值方式:NSKeyedArchiver和NSKeyedUnarchiver,实例变量可按任意的次序编解码。

顺序方式:NSArchiver和NSUnarchiver,以某种次序编码实例变量。解码的时候,仍要使用相同的次序。

3.code示例

定义类

#import <Cocoa/Cocoa.h>

@interface codeObj : NSObject <NSCoding>

{
NSString *name;
int magicNumber;
float shoseSize;
NSMutableArray *subThingies;
}
@property (copy) NSString *name;
@property int magicNumber;
@property float shoseSize;
@property (retain) NSMutableArray *subThingies;

-(id) initwithName:(NSString *) n
       magicNumber:(int) mn          shoseSize:(float) ss;

@end
#import "codeObj.h"
@implementation codeObj

@synthesize name;
@synthesize magicNumber;
@synthesize shoseSize;
@synthesize subThingies;

-(id) initwithName:(NSString *) n
       magicNumber:(int) mn          shoseSize:(float) ss{
if(self=[super init]){
self.name=n;
self.magicNumber=mn;
self.shoseSize=ss;
self.subThingies=[NSMutableArray array];
}
return (self);
}

-(void) dealloc{
[name release];
[subThingies release];
[super dealloc];
}
//NScoding协议的方法
-(void) encodeWithCoder:(NSCoder *) coder{
[coder encodeObject:name forKey:@"name"];
[coder encodeInt:magicNumber forKey:@"magicNumber"];
[coder encodeFloat:shoseSize forKey:@"shoseSize"];
[coder encodeObject:subThingies forKey:@"subThingies"];
}

-(id) initWithCoder:(NSCoder *)  decoder{
if(self =[super init]){
self.name=[decoder decodeObjectForKey:@"name"];
self.magicNumber=[decoder decodeIntForKey:@"magicNumber"];
self.shoseSize=[decoder decodeFloatForKey:@"shoseSize"];
self.subThingies=[decoder decodeObjectForKey:@"subThingies"];
}
return (self);
}

-(NSString *) description{
NSString *descripton=[NSString stringWithFormat:@"%@:%d,%.1f,%@",name,magicNumber,
shoseSize,subThingies];
return (descripton);
}

@end

实例对象归结档

#import "codeObj.h"
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
codeObj *thing;
thing=[[[codeObj alloc] initwithName:@"name" magicNumber:20 shoseSize:30.5] autorelease];
NSLog(@"--------%@",thing);//将自建类转换为NSData类型
NSData *freezeDrid;
freezeDrid=[NSKeyedArchiver archivedDataWithRootObject:thing];//将NSData写入文件
[freezeDrid writeToFile:@"/tmp/codeobj.txt" atomically:YES];
codeObj *anotherThing;
anotherThing=[[[codeObj alloc] initwithName:@"ssssss" magicNumber:20 shoseSize:4.5] autorelease];
[anotherThing.subThingies addObject:thing];

NSData *other;
other=[NSKeyedArchiver archivedDataWithRootObject:anotherThing];
//写入文件
[other writeToFile:@"/tmp/objandobj.txt" atomically:YES];
//从文件中读取出NSData
NSData *fileData;
fileData=[NSData dataWithContentsOfFile:@"/tmp/objandobj.txt"];//将NSData转换为自建类
codeObj *fromFile;
fromFile=[NSKeyedUnarchiver unarchiveObjectWithData:fileData];
NSLog(@"------%@",fromFile);
    [pool drain];
    return 0;
}

或者可以

#import "codeObj.h"
int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
codeObj *inThing;codeObj *outThing;
inThing=[[[codeObj alloc] initwithName:@"name" magicNumber:20 shoseSize:30.5] autorelease];
NSLog(@"--------%@",thing);//存入文件(归档)
NSString *path;//假设path已经有值path = [[NSString alloc] initWithFormat:@"%@%@",path,@"/code.txt"]; [NSKeyedArchiver archiveRootObject:inThing toFile:path];
//从文件中读取(解档)
outThing=[NSKeyedUnarchiver unarchiveObjectWithFile:path];

}
时间: 2024-10-12 20:42:30

类的序列化和反序列化、对象的归档个解档的相关文章

初识序列化和反序列化,使用BinaryFormatter类、ISerializable接口、XmlSerializer类进行序列化和反序列化

序列化是将对象转换成字节流的过程,反序列化是把字节流转换成对象的过程.对象一旦被序列化,就可以把对象状态保存到硬盘的某个位置,甚至还可以通过网络发送给另外一台机器上运行的进程.本篇主要包括: ● 使用BinaryFormatter类进行序列化和反序列化● 使用ISerializable接口自定义序列化过程● 使用XmlSerializer类进行序列化和反序列化 □ 使用BinaryFormatter类进行序列化和反序列化 首先把需要序列化的类打上[Serializable]特性,如果某个字段不需

.Net类的序列化和反序列化 - 进阶者系列 - 学习者系列文章

今天看了下以前的一个工具的代码,其中涉及到.NET类的序列化和反序列化问题,所以就写一下. 这里说一下.NET类序列化的好处..NET类在序列化之前只是一个相对狭义的类.通过序列化,能够更好的保存该类的形式,也能够更好的通过XML来保存类的内容.通过类的反序列化,我们就能够更好的获取该类的内容,也能够更好的通过XML操作的方式来访问该类的内容. 下面我们来看看类序列化的方法. 这里提供了两个方法.第一个方法很简单,直接传入一个对象,然后通过XmlSerializer类来进行获取该类的内容,为下面

OC-自定义对象的归档与解归档

对于系统对象进行归档与接归档直接使用类提供的方法 参考:http://www.cnblogs.com/BeyondAverage0908/p/4596798.html 但是对于自定义的对象,当使用系统的类方法进行归档和解归档时,就会出现内存错误,错误信息是没有实现(归档时)- (void)encodeWithCoder:(NSCoder *)aCoder;方法,(解归档)时没有实现:- (id)initWithCoder:(NSCoder *)aDecoder; 所以如果需要自定义对象的归档与解

OC-多个自定义对象的归档与解归档

对于上一章节,简单讲述了一个自定义对象的归档与解归档:http://www.cnblogs.com/BeyondAverage0908/p/4597245.html 本章节阐述下多个自定义对象的归档与解归档 以下代码阐述:定义了两个类Dog和Cat,并且利用@property展开了对应的几个属性(简单的代码,不贴源码了). 以下代码部分位主要的归档与解归档代码:注意需要在对应的自定义类中实现以下两个方法:- (void)encodeWithCoder:(NSCoder *)aCoder;方法,-

C# 类的序列化和反序列化

序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程.在序列化期间,对象将其当前状态写入到临时或持久性存储区.以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象.(摘自百度百科) 在很多通讯或者数据存储的过程中,都需要序列化和反序列化的过程. 在C#中,如果想要进行自定义类的序列化,只需要简单地在定义类的时候添加Serializable标签即可.如: 1 2 3 4 5 6 [Serializable] public class Person {

内部类,drf响应类,序列化与反序列化

内部类 # 概念:将类定义在一个类的内部,被定义的类就是内部类 # 特点:内部类及内部类的所以名称空间,可以直接被外部类访问的 # 应用:通过内部类的名称空间,给外部类额外拓展一些特殊的属性(配置),典型的Meta内部类 - 配置类 class Book(model.Model): class Meta: db_model = "owen_book" # 配置自定义表名 class BookSerializer(serializers.ModelSerializer): class M

Msgpack序列化及反序列化对象

MessagePack是一个基于二进制高效的对象序列化类库,可用于跨语言通信.它可以像JSON那样,在许多种语言之间交换结构对象:但是它比JSON更快速也更轻巧.支持Python.Ruby.Java.C/C++等众多语言.比Google Protocol Buffers还要快4倍. 代码地址:https://github.com/msgpack/msgpack 官网地址:http://msgpack.org/ MessagePack的优势是速度比较快,支持众多语言,便于不同语言开发的系统之间交换

C#序列化与反序列化(Serialize,Deserialize)实例详解

这篇文章主要介绍了C#序列化与反序列化(Serialize,Deserialize)的方法,实例分析了C#序列化与反序列化的常见技巧,需要的朋友可以参考下 本文实例讲述了C#序列化与反序列化(Serialize,Deserialize)实现方法.分享给大家供大家参考.具体分析如下: 如果要保存运行程序过程的数据要么保存到数据库中,要么新建一个普通的文件,然后把数据保存进去.但是这两者有个缺点就是,不能把原有数据的结构也保存进去.比如一个类中的字段值保存进去后再读取出来必须再解析下才行.序列化技术

IOS开发——UI进阶篇(十一)应用沙盒,归档,解档,偏好设置,plist存储,NSData,自定义对象归档解档

1.iOS应用数据存储的常用方式XML属性列表(plist)归档Preference(偏好设置)NSKeyedArchiver归档(NSCoding)SQLite3 Core Data 2.应用沙盒每个iOS应用都有自己的应用沙盒(应用沙盒就是文件系统目录),与其他文件系统隔离.应用必须待在自己的沙盒里,其他应用不能访问该沙盒应用沙盒的文件系统目录,如下图所示(假设应用的名称叫Layer)模拟器应用沙盒的根路径在: (apple是用户名, 8.0是模拟器版本)/Users/apple/Libra