对象的编码把对象的类特征以及对象状态转化为某种格式(二进制),这种格式可以存储,也可以在进程间和网络间传递。
类的类型以及实例数据会被写入到某种字节流中,当程序结束的时候,该字节流可以进行持久化。程序启动的时候,新分配的对象可以解码之前保存的自身描述,然后把自己恢复到之前运行时的状态。编码通常需要和归档协作。归档将对象转化成一种可以写进文件系统的格式(档案)。解档则是在档案上执行操作。在此过程中,保存在档案的对象需要对自身进行解码。
所以,如果需要将某种类型的实例对象进行归结档,则首先需要对该类进行序列化和方序列化(编解码),该类需遵循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