//  codeObj.h
#import <Cocoa/Cocoa.h>



/**

cocoa具备一种机制来将对象自身转换为某种格式并保存中磁盘上。

对象可以将它们的实例变量和其他数据编码为数据块,然后保存到磁盘中。以后将这些数据块都会到内存中,并且

还能基于保存的数据创建新对象。这个过程称为编码和解码,或称为序列化和反序列化。

*/

/**

要编码的对象,必须实现NSCoding协议。

@protocol NSCoding

-(void) encoderWithCoder:(NSCoder *) aCoder;

-(id) initWithCoder:(NSCoder *) aDecoder;

@end

当对象需要保存自身时-encoderWithCoder:方法被调用

当对象需要加载自身时-initWithCoder:方法被调用

*/

@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


//  codeObj.m

//  encodeObject

//

//  Created by 110 on 10-2-6.

//  Copyright 2010 __MyCompanyName__. All rights reserved.

//



#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"];

}

/**

initWithCode:和其他init方法一样,中对对象执行操作之前,需要使用超类对它们进行初始化。为此,可以采用

两种方式,具体取决于父类,如果父类采用了NSCoding协议,则应该调用[super initWithCoder:decoder];

否则,只需要调用[super init]即可。NSObject不采用NSCoding协议,因此我们可以使用简单的init方法

*/



/**

decodeObjectForKey:把一个对象从×××中取出

decodeIntForKey:把int从×××中取出,在嵌入的对象上递归使用initWithCoder:方法。

*/

-(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);

/**

+archivedDataWithRootObject:类方法编码thing对象。首先,它在后台创建一个NSKeyedArchiver实例

,然后,它将NSKeyedArchiver实例传递给对象thing的-encodeWithCoder:方法。当thing编码自身的属性时

,它可能对其他对象也进行编码,例如字符串,数组以及我们可能输入到该数组中的任何内容。整个对象集合完成键和值的编码后,具有键/值对的归档程序将所有对象扁平化为一个NSData类并将其返回.

*/

NSData *freezeDrid;

freezeDrid=[NSKeyedArchiver archivedDataWithRootObject:thing];

[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 *fileData;

fileData=[NSData dataWithContentsOfFile:@"/tmp/objandobj.txt"];

codeObj *fromFile;

fromFile=[NSKeyedUnarchiver unarchiveObjectWithData:fileData];

NSLog(@"------%@",fromFile);

   [pool drain];

   return 0;

}