12

あなたがオブジェクトのパブリックプロパティを検査し、encodeWithCoderの一般的な実装を生成することで、一般的なNSCoding実装を書くことができるようになるのObjective-Cでの反射のいずれかの手段があります:とinitWithCoder:。のObjective-Cの反射

私は、リフレクションを使用してJavaオブジェクトをシリアライズおよびデシリアライズする一般的な方法を可能にするJavaのためのXStreamのようなものと思っています。さらに優れているのは、直列化したいプロパティや一時的なプロパティ(Javaのtransientキーワードなど)としてプロパティをマーキングするための手段でしょう。

私はココアのためArchives and Serializations Programming Guide上のドキュメントを読んでいます。私はあなたのオブジェクトのシリアル化をいくつかコントロールしたいと思っていますが、一般に対称的なプロセスであり、シリアライズのためにコード化されているものを逆シリアル化する必要があるのは奇妙です。私はDRYを信じています(繰り返しません)。

答えて

12

だけでなく、それは可能ですが、私は正確にそれを行うに刺しを取っています友人がいます。 (彼のblog about it hereを見ることができます)。反映は、Objective-C 2.0 Runtime Referenceに記載されているObjective-Cランタイム関数を使用して行われます。見てみましょう。

ただし、あなたはすべてのインスタンス変数を保存する一般的な振る舞いをしたい場合にのみ動作すること。しかし、NSViewにスーパービューを保存させたくないかもしれません。そのような場合、一般的なケースは機能しません。

保存するインスタンス変数のプロパティを宣言し、他の変数を「隠して」おくことで、シリアル化するものとシリアル化しないものを区別することができますが、それはプロパティの目的全体をひねります小さな利益に。私はそれをお勧めしません。

6

(私はBJホーマーさんのコメントににリンクされているブログの記事の著者でいます)。コードを使用する場合の注意点がいくつかあります。

  1. ターゲットクラスはKVCに準拠している必要があります。 ivarsにObjective-C 2.0のプロパティを使用している場合は、すべて設定されています。それ以外の場合は、クラスがvalueForKey:およびsetValue:forKey:メソッドに正しく応答するように設定されていることを確認する必要があります。
  2. このコードでは、ランタイムのドキュメント化されていない「機能」を使用して、ivarクラスをNSCodingに再帰的に適合させています。コンパイルすると、ほぼすべてのタイピング情報(AFAIK)がコードから取り除かれますが、イヴァールを保存するには、もNSCodingに準拠する必要があります。私は、ivarがオブジェクトで、その上にivar_getTypeEncoding()を呼び出すと、{#IVAR_CLASS}(例:{#NSString})のような文字列が返されることを発見しました。 #と#の間の文字列を取得し、NSClassFromStringを使用してClassオブジェクトを作成し、そのオブジェクトを再帰させます。
  3. このコードはすべてのivarsを保存します。
  4. (もちろん)ご自身の責任で利用

私は主にコンセプトの証明としてこれを書いて、そしてこのコードは見事に失敗したときに多くのインスタンスがあります。たとえば、オブジェクトAにBのivarがあり、BにAのivarがある場合、コードを使用して一方または他方を直列化すると、無限ループが発生します。

しかし、私はObjective-Cが最初のようなことをすることさえ可能にするのはすごく面白いと思います。しかし、

http://www.realmacforge.com/svn/trunk/RMModelObject/

にObjCランタイムのものは10.5であり、シミュレータではなく、実際にiPhone上で動作することに注意してください:

0

はRMModelObjectをチェックしてください。ハードな方法を見つけました.. OS 3.0が最終的にそれをサポートしているかもしれませんが、私はチェックしていません。