EOIFGenerateObjects

2007/03/30 (Fri) 22:07:46 JST

データ行をフェッチし、オブジェクトの識別子であるグローバルIDと、データのテンプレートであるスナップショットが揃いました。 いよいよここからオブジェクトを生成します。

具体的には、オブジェクトを生成してオブジェクトグラフに登録します。 グローバルIDに関連づけられたオブジェクトは、フェッチに使用したEOEditingContextのオブジェクトグラフに登録されます。

1. オブジェクトグラフを確認する

まず、先のグローバルIDに対応するオブジェクトが存在するかどうか、EOEditingContextのオブジェクトグラフを確認します(objectForGlobalID())。 すでにオブジェクトが存在し、フォールトでなければそのオブジェクトを返してfetchObject()は終了です。

2. オブジェクトを生成する

EOEntityClassDescription.createInstanceWithEditingContextを呼び出し、オブジェクトを生成します。 ?EOEntityClassDescriptionはオブジェクトに対応するエンティティを探すので、カスタムクラスのオブジェクトでもこのメソッドによって生成することができます。 この時点ではオブジェクトの中身は空です。

3. オブジェクトグラフへオブジェクトを登録する

生成したオブジェクトをEOEditingContext.recordObject()でオブジェクトグラフに登録します。 以降、基本的に同じデータ行をフェッチしてもこのオブジェクトが使われます。

4. オブジェクトを初期化する

最後にEOEditingContext.initializeObject()を呼び出してオブジェクトを初期化します。 ここで初めてスナップショットのデータがオブジェクトにセットされ、リレーションシップがある場合はフォールトが作成されます。

次が最終的に生成されるオブジェクトの内容です(見やすいよう一部クラス名を省略)。 スナップショットと違ってクラスプロパティのみが含まれ、リレーションシップにはフォールトがセットされます。 主キー・外部キーはクラスプロパティにしていないのでオブジェクトには含まれません。

{
 // オブジェクトとグローバルID([]が対応するグローバルID)
 this = "<EOGenericRecord [Movie 205]>";

 // プロパティの内容
 values = {
   rated        = "G";
   plotSummary  = "<EOGenericRecord
                   (EOAccessFaultHandler [PlotSummary 205])>";
   voting       = "<EOGenericRecord
                   (EOAccessFaultHandler [Voting 205])>";
   dateReleased = 1996-01-24 20:00:00 Etc/GMT;
   movieRoles   = "<_EOCheapCopyMutableArray 8f5cce
                   (<EOAccessArrayFaultHandler
                      movieRoles [Movie 205]>)>";
   posterName   = <NSKeyValueCoding$Null>;
   studio       = "<EOGenericRecord
                   (EOAccessFaultHandler [Studio 52])>";
   title        = " EOF Next Generation";
   directors    = "<_EOCheapCopyMutableArray 57c7bf
                   (<EOAccessArrayFaultHandler
                      directors [Movie 205]>)>";
   reviews      = "<_EOCheapCopyMutableArray f27273
                   (<EOAccessArrayFaultHandler
                      reviews [Movie 205]>)>";
   revenue      = 600000.00;
   category     = "Surreal";
   trailerName  = <NSKeyValueCoding$Null>;
 };
}

?FaultHandlerとあるものはフォールトです。 このときは単なる空のオブジェクトで、フォールトの内容を参照するときにデータがフェッチされます。 ?EOAccessFaultHandlerが1対1のフォールト、?EOAccessArrayFaultHandlerが1対多のフォールトです。

?FaultHandlerは単体でフォールトを表すのではなく、フォールトを示すフラグとしてオブジェクトにセットされます。 例えばplotSummaryには?EOGenericRecordがセットされていますが、この?EOGenericRecordには?EOAccessFaultHandlerがセットされており、1対1のフォールトであることを表しています。

一方、movieRolesなどの1対多のフォールトは?EOGenericRecordの代わりに_?EOCheapCopyMutableArrayというNSArrayのサブクラスが使われています。 このクラスは内部で使われているものでAPIリファレンスには書いてありませんが、外から見る限りではNSArrayと変わりません。 ただ1つ異なるのは、メッセージを受け取る(メソッドを呼び出す)と自動的にフォールトを補充することです。 ユーザーに何も意識させることなく、必要なデータをフェッチします。


Inverse Pages: フェッチの舞台裏