initWithCoder?編碼與解碼(序列化與反序列化)

//  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;

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章