ページ

2008年2月26日火曜日

NSRect を CoreDataで扱う(その2)

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

前回紹介したサイトに掲載されていたNSKeyedArchiver にカテゴリを追加する方法を試してみる。


まず CoreDataへ行く前に NSKeyedArchiver/NSKeyedUnarchiver を実装した簡単なサンプルで試してみる。

ソースコード:ArchiveSample.zip



"Archive" ボタンを押すと NSRect {{10, 20} , {100, 200}}がデスクトップ上に archiver.sampleというファイル名で保存される。
"UnArchive" ボタンを押すと archiver.sampleを読み込み、NSRectに戻して画面に表示する。

MyController.m

-(id)init
{
if (self = [super init]) {
rect = [[NSValue valueWithRect:NSMakeRect(10, 20, 100, 200)] retain];
rect_string1 = NSStringFromRect([rect rectValue]);
rect_string2 = @"";
}
return self;
}


インスタンス変数 rect がArchiver対象のNSRect。rect_string1, 2 は画面表示用の文字列でラベルから bindingされている(文字列を変更すると画面に反映される)。

- (IBAction)archive:(id)sender
{
BOOL result = [NSKeyedArchiver archiveRootObject:rect toFile:[self filename]];
}


Archiverボタンが押されたら NSKeyedArchiver#archiveRootObject:toFile: で rectを指定し保存を行う。通常では NSKeyedArchiverは構造体をサポートしていないので下記のエラーが出る。

*** -[NSKeyedArchiver encodeValueOfObjCType:at:]: this archiver cannot encode structs



そこで サイトに紹介されていたコードを拝借してカテゴリで Cの構造体をサポートするコードを追加する。

@interface NSKeyedArchiver (MyKeyedArchiver)
- (void)encodeValueOfObjCType:(const char *)valueType at:(const void *)address;
@end

@implementation NSKeyedArchiver (MyKeyedArchiver)
- (void)encodeValueOfObjCType:(const char *)valueType at:(const void *)address
{
NSMutableData *datas = [NSMutableData data];
NSArchiver *arch = [[NSArchiver alloc] initForWritingWithMutableData:datas];
[arch encodeValueOfObjCType:valueType
at:address];
[self encodeObject:[NSData dataWithData:datas]];
[arch release];
}
@end


するとエラーが出なくなる。

UnKeyedArchiverも同様にカテゴリを追加する。

- - - -
さて次回は CoreData で使ってみる。