2012-01-03 6 views
3

クラス全体でNSCodingを使用してセーブ/ロード機能を持つゲームが公開されています。私たちは現在次のバージョンを扱っていますが、その前にコードをリファクタリングする必要がありますので、パフォーマンスが向上し、将来の機能を実装するのが容易になります(これは変更が多い傾向にあります)。NSKeyedArchiverでエンコードされたオブジェクトの階層を変更するには?

問題は新しいデザインをレビューした後です。これは、以前のバージョンとは異なるNSCoding階層を持ちます。

v1.0をGameSavedFile(NSKeyedArchiverを使用して) - > UserDataを - >ユーザ(UserDataをの親) - >オブジェクトとプリミティブ

V1.1ユーザー(NSKeyedArchiverを使用)の束 - >オブジェクトの束とプリミティブ

v1.1は、より単純でより簡単な構造を持っています。 v1.0では、UserDataはUserのサブクラスですが、v1.1ではすべてのUserデータに対して1つのクラスのみを使用します。

この方法は簡単で実用的です。しかし、どうすればv1.0のすべてのデータをv1.1に移植することができますか?私はsetClassName:forClass:メソッドがあると読んだが、私は新しいクラスの古いクラスを置き換えると思う。

私が考えることができる最もクリーンで安全な方法は、ゲームがまだ古いバージョン(v1.0)を使用しているかどうかを確認することです。そうであれば、NSCoding階層をplist/dictionaryに変換し、それをv1.1コードに散らばります。

私は可能な提案/解決策については公開していますが、可能であれば、Foundationフレームワークですでに利用可能なソリューションを選ぶことをお勧めします。

ありがとうございました。

答えて

2

もちろん、あなたはForward and Backward Compatibility for Keyed Archivesを読むべきですが、ここであなたの問題に実際には触れません。 (とにかくそれをお読みください。)

をあなたはまだV1.1を出荷していないと仮定すると、ここに私の推薦である:

  • はv1.1のための新たな保存ファイル名を作成します。私はしばしばこれを簡略化するためにファイル名にバージョン番号を含めます。これにより、開く前にどのバージョンを読み込もうとしているかを簡単に知ることができます。私は一般的に、このバージョンをファイルに保存するというAppleの推奨よりも好きです。 (もちろん、ファイル名を変更するとユーザーの混乱が生じる場合や、ユーザーがファイル名を制御できる場合は、ファイルにバージョンを保存する必要があります)。

  • v1.0ファイルの場合は、V10GameSaveFile生データを保持する。次に、setClassName:forClass:を使用して、シリアライズされたオブジェクトをダミークラスクラスに移動します。

  • これで構造がメモリに保存され、新しいオブジェクトモデルに変換され、元のファイルが再保存され、削除されました。

+0

これを試してみます。ありがとう。 – Sylpheed

+0

完全に動作します。ありがとう。 これは良いアプローチですか?私は上司とこの問題について議論しました。彼は保存/読み込みのためのバージョン固有のコードを含まないように私に伝え続けます。確かに、nullフィールドにデフォルト値を割り当てることができますが、階層が変更されたときに、バージョン固有のコードが悪い理由がわかりません。 – Sylpheed

+0

多くの場合、バージョン固有のコードがロードされていることが絶対に必要です。それはプログラムの残りの部分でそれを心配する必要はないように、ローディングコードに分離する必要がありますが、古いスキーマを知っているプログラムの一部がなければなりません。 –

関連する問題