カスタムオブジェクトの永続化
-
22-07-2019 - |
質問
NSObjectを単純に継承するカスタムオブジェクトがあります。 2つのフロートと NSDate
の3つのメンバーがあります。
私のアプリには、これらのオブジェクトの多くが動き回る配列があり、実行間で永続化する必要があります。どうすればこれを達成できますか?
SQLite dbを使用することを考えましたが、私がやるのは select *
だけであるため、少しやり過ぎだと思います。
理想的な世界では、xml plistファイルを使用します。ただし、カスタムオブジェクトを使用してこれを実行できるかどうかはわかりません。プロパティリストオブジェクトのセットがあり、 NSArray
がその下にあることは知っていますが、 writeToFile:atomically:
はプロパティリストオブジェクトでのみ機能します。
ご意見をお寄せいただきありがとうございます!
解決
NSCoding
はまさにあなたが望むことをします。 Appleのドキュメントを読むことをお勧めしますが、使用するのは非常に簡単だと思いました。クラス(およびすべての子クラス)は NSCoding
プロトコルを実装する必要があり、 -encodeWithCoder:
および -initWithCoder:
を追加する必要がありますオブジェクトへのメソッド。共通のフレームワーククラスのほとんどは、既に NSCoding
を実装しています。
クラスのコードは次のようになります。
-(void) encodeWithCoder: (NSCoder*) coder {
[coder encodeInteger: versionValue forKey: versionKey];
[coder encodeObject: myStuff forKey: myStuffKey];
}
-(id) initWithCoder: (NSCoder*) coder {
self = [super init];
if ( ! self) return nil;
myStuff = [[coder decodeObjectForKey: myStuffKey] retain];
return self;
}
将来のバージョンでアーカイブ形式の変更を柔軟に管理できるように、エンコード時にバージョン番号を追加することをお勧めします。
クラスに、オブジェクトをアーカイブするための便利なメソッドを追加しました:
-(void) archiveToFile: (NSString*) path {
NSMutableData *data = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData: data];
[archiver encodeObject: self forKey: myArchiveKey];
[archiver finishEncoding];
[archiver release];
[data writeToFile: path atomically: YES];
[data release];
}
および別のオブジェクトをアーカイブ解除するか、新しいオブジェクトを作成します:
+(MyArchive*) newFromFile: (NSString*) path
orWithMyStuff: (MyStuff*) myStuff
{
NSData *data = [[NSData alloc] initWithContentsOfFile: path];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData: data];
MyArchive *myArchive = [unarchiver decodeObjectForKey: myArchiveKey];
[unarchiver finishDecoding];
if (myArchive) {
[myArchive retain];
} else {
myArchive = [[MyArchive alloc] initWithStuff: myStuff;
}
[unarchiver release];
[data release];
return myArchive;
}
トップレベルのオブジェクトは NSArray
であるため、ケースの最後の2つのメソッドを変更する必要がありますが、ボイラープレートコードのほとんどは同じです。
他のヒント
オブジェクトのサブセットを取得する場合は、SQLiteが最適です。
そうでない場合は、plist形式とNSCodingから選択します。 plistを使用するには、カスタムオブジェクトをplistに適したものに変換してから、plistをオブジェクトに戻す必要がありますが、NSCodingは頭を包むのが少し難しく、手で簡単に編集(または検査)できません。