Cocoaでシリアライズ (NSCoding)

自作のクラスをシリアライズするための便利な機能がCocoaには用意されています。
それが NSCoding、NSKeyedArchiver、NSKeyedUnarchiver です。

NSCodingプロトコルは NSString、NSNumberやNSArray、NSDictionaryなどなど、良く使うデータクラスには既に実装されていますが、自作クラスには自分で実装する必要があります。

NSCodingの実装

まずは、対象となるクラス(子オブジェクトも全て)にプロトコル[NSCoding]を実装しておきます。
宣言部はこんな感じです。

@interface DBConnectionInfo : NSObject<NSCoding>

@property (nonatomic,retain) NSString* endpoint;
@property (nonatomic,assign ) int retryCount;

@end

実装は initWithCoder、encodeWithCoder を下記のような感じで。

@implementation DBConnectionInfo
#pragma mark -
#pragma mark NSCoding impl

- (id)initWithCoder:(NSCoder *)coder
{
    self = [super init];
    if (self)
    {
        self.endpoint = [coder decodeObjectForKey:@"endpoint"];

        self.retryCount = [coder decodeInt32ForKey:@"retryCount"];
    }
    return self;

}

- (void) encodeWithCoder:(NSCoder *)encoder
{
     [encoder encodeObject:self.endpoint forKey:@"endpoint"];
     [encoder encodeInt32:self.retryCount forKey:@"retryCount"];
}

シリアライズ処理

NSCodingを実装したクラスをシリアライズするには NSKeyedArchiver を使います。
下記ではシリアライズした結果を NSUserDefaults に保存してみました。


DBConnectionInfo* _connectInfo;


//接続のリストをシリアライズ
NSMutableData* connectData = [NSMutableData data];
NSKeyedArchiver *encoder = [[NSKeyedArchiver alloc] initForWritingWithMutableData:connectData];
[encoder encodeObject:_connectInfo forKey:@"connectData"];
[encoder finishEncoding];
[encoder release];

//シリアライズした情報をNSUserDefaultsに保存してみます
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];    
[defaults setObject:connectData forKey:@"connectionList"];    
[defaults synchronize];

※キーを指定してシリアライズしていますが、一つのオブジェクトだけをシリアライズするのであれば archivedDataWithRootObject: を使うとNSDataが直接とれて簡単です。

デシリアライズ処理

インスタンスを復元させるには NSKeyedUnarchiver を使います。


//NSUserDefaultsからシリアライズしたデータを取得
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData* connectData = [defaults dataForKey:@"connectionList"];    

//デシリアライズ
NSKeyedUnarchiver *decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:connectData];    
_connectInfo = [decoder decodeObjectForKey:@"connectData"];
[decoder finishDecoding];
[decoder release];

cocoaフレームワークのおかげでかなり簡単に実装できちゃいますね。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です