Stork Lab

NSKeyedArchiver インスタンスを保存

NSKeyedArchiverを使うとインスタンスをそのまま保存することができます。しかし、これはJavaのように自動でやってくれるものではなくNSCodingというプロトコルを実装しなければなりません。ほとんどのCocoa APIのクラスには実装されていますが、自分でクラスを作った場合にはこれを自分で実装しなければなりません。とりあえずBlock GetterでNSCodingを実装しているクラスのサンプル。
//  RankData.h
//  BlockGetter

#import <Cocoa/Cocoa.h>


@interface RankData : NSObject <NSCoding> {
	@private
	
	long _totalTime;
	int _totalTurn;
	int _score;
}

- (id)initWithTime:(long)totalTime turn:(int)totalTurn score:(int)score;
- (BOOL)higherThanThis:(RankData *)data;
- (long)totalTime;
- (int)turn;
- (int)score;

@end
//  RankData.m
//  BlockGetter

#import "RankData.h"


@implementation RankData

- (id)initWithTime:(long)totalTime turn:(int)totalTurn score:(int)score
{
	_totalTime = totalTime;
	_totalTurn = totalTurn;
	_score = score;
	
	return self;
}
- (BOOL)higherThanThis:(RankData *)data
{
	if([data score] > _score){
		return NSOrderedDescending;
	}else if([data score] == _score){
		return NSOrderedSame;
	}
	return NSOrderedAscending;
}
- (long)totalTime
{
	return _totalTime;
}
- (int)turn
{
	return _totalTurn;
}
- (int)score
{
	return _score;
}
- (void)encodeWithCoder:(NSCoder*)coder
{
	[coder encodeInt:_totalTime forKey:@"TIME"];
	[coder encodeInt:_totalTurn forKey:@"TURN"];
	[coder encodeInt:_score forKey:@"SCORE"];
}
- (id)initWithCoder:(NSCoder*)decoder
{
	[super init];
	_totalTime = [decoder decodeIntForKey:@"TIME"];
	_totalTurn = [decoder decodeIntForKey:@"TURN"];
	_score = [decoder decodeIntForKey:@"SCORE"];
	
	return self;
}
@end
ここで重要な部分は赤で示したところです。
この部分でファイルにインスタンスの情報を書き込みます。書き込みには[coder encodeInt:##VALUE## forKey:##KEY##];を使い、読み出しには[coder decodeIntForKey:##KEY##];を使います。このメソッドにはint型のみでなくそれ以外のいくつかの型が扱えます。もし、CocoaのAPIのサブクラスでこの二つのメソッドを呼び出す時はあらかじめ
[super encodeWithCoder:coder]
[super initWithCoder:decoder]
をそれぞれ書いておく必要があります。
このとき、NSArchiverを使うとキーを設定できず、decodeやencodeを呼び出す順番でどの情報が呼び出されるかが決まります。