Apple Developer Connection
Advanced Search
Member Login Log In | Not a Member? Contact ADC


管理対象オブジェクトの使用

この文書では、アプリケーションにおける管理対象オブジェクトの使用と操作に関連する問題について説明します。

このセクションの内容:

管理対象オブジェクトの変更
メモリ管理
コピーとペースト
検証
関係とフォールト
データの確実な更新

管理対象オブジェクトの変更

管理対象オブジェクトのプロパティを変更するには、デフォルトでは、(管理対象オブジェクトモデルで定義した)プロパティの名前をキーとしてキー値コーディングを使用します。この一般原則は属性と関係の両方に適用されます。対多関係については、後で説明するように、特に考慮すべき事柄がいくつかあります。

以下の例では、単純な属性の変更について示します。対一関係の変更にも同じテクニックを適用できます。

[newEmployee setValue:@"Jo" forKey:@"firstName"];

特定エンティティのカスタムクラスを定義し、独自のアクセサメソッドを実装した場合は(実装の詳細については、『NSManagedObject』の「Subclassing Notes」を参照)、以下の例に示すように、それらを直接呼び出すことができます。

[newEmployee setFirstName:@"Jo"];

もちろん、カスタムクラスとカスタムアクセサを指定した場合も、キー値コーディングが使えます。

対多関係を変更する場合も、キー値コーディングを使いますが、mutableSetValueForKey: を使用します。このメソッドは、関係を変化させ、適切なキー値監視通知を送るという 2 つの処理を行うプロキシオブジェクトを返します。通常は、対多関係を対象に独自のコレクションアクセサメソッド(add<Key>Object: および remove<Key>Object: など)を実装するべき理由はほとんどありませんが、実装した場合はこれらを直接呼び出すことができます(カスタムアクセサを実装する場合は、注意して add<Key>Object:remove<Key>Object: のペア、または add<Key>:remove<Key>: のペア、あるいは両方のペアを実装する必要があります。そして、これらが、関連する KVO 通知を確実に送るようにします。実装の詳細については、『NSManagedObject』の「Subclassing Notes」を参照してください)。関係変更の詳細については、「関係の操作」を参照してください。

メモリ管理

一般に、管理対象オブジェクトを使用する際は、標準の Cocoa メモリ管理ガイドラインに従いましょう。ただし、考慮すべき問題がいくつかあります。

留意すべきもう 1 つの問題は、ビュー(またはコントローラ)オブジェクトが一般的に、表示(または管理)するオブジェクトを保持するということです。これが特に関連するのは、NSController のサブクラスがそれらのコンテンツオブジェクトを保持する Cocoa バインディングを使用する場合です。

コピーとペースト

管理対象オブジェクトのコピーとペーストに関する問題を一般的な方法で解決するのは困難です。オブジェクトグラフのどの部分を実際にコピーするのかを、ケースバイケースで判断する必要があります。

多くの場合は、コピー時に管理対象オブジェクトを表すディクショナリ(プロパティリスト)を作成し、ペースト時に新しい管理対象オブジェクトを作成し、ディクショナリを使用して内容を設定するのが最善策です。例については、『NSPersistentDocument Core Data Tutorial』を参照してください。

検証

管理対象オブジェクトモデルでは、プロパティが持ちうる値に制約を設けることができます(たとえば、Employee の給与はマイナスにできないとか、どの従業員も Department に所属しなければならないというような制約です)。

validateForUpdate: を使用すれば、こうした制約がすべて満たされているかどうかを確認することができます。1 つの操作に複数の検証エラーがある場合、それらのエラーは userInfo ディクショナリの配列に集められます。そこからエラーを取り出すには、NSDetailedErrorsKey キーを使用します。

管理対象オブジェクトは新しい値と、モデルに指定されている制約を比較します。

また、validateValue:forKey:error: を使用して、個別の値を検証することもできます。たとえ validate<Key>:error: という形式のカスタム検証メソッドを実装した場合でも、通常はカスタム検証メソッドを直接呼び出すべきではありません。その代わりに、適切なキーを指定して validateValue:forKey:error: を呼び出すようにします。これにより、管理対象オブジェクトモデルに定義されている制約がすべて確実に適用されます。

関係とフォールト

管理対象オブジェクトは通常、永続ストアに保管されているデータを表します。ときには、管理対象オブジェクトが「フォールト」(プロパティ値が外部ストアからまだロードされていないオブジェクト)であることもあります。永続プロパティ値にアクセスすると、フォールトが「発動」し、その永続データがストアから自動的に取り出されます。状況によっては、管理対象オブジェクトを明示的にフォールトに変えることも考えられます(通常は、NSManagedObjectContext の refreshObject:mergeChanges: を使用して、値を最新の状態にすることを目的とします)。もっと一般的には、関係を渡り歩いているときにフォールトに遭遇します。

関係

管理対象オブジェクトを受信しても、Core Data は関係の対象となっている他のオブジェクトに関するデータを自動的には受信しません(「フォールティング」を参照)。最初、オブジェクトの関係はフォールトで表されます(対象オブジェクト自体がすでに受信されていないかぎり−「一意化」を参照)。しかし、関係の対象オブジェクトにアクセスすると、それらのデータが自動的に取得されます。たとえば、アプリケーションを初めて起動したときに、永続ストアから Employee オブジェクトを 1 つ受信すると、(以降のものが永続ストアにあると仮定して)その manager および department 関係はフォールトとして表されます。それでも、次のコード例に示すように、従業員の上司のラストネームを要求することができます。

NSString *managersName = [[anEmployee valueForKey:@"manager"] valueForKey:@"lastName];

あるいは、もっと簡単に、キーパスを使用します。

[NSString *managersName = anEmployee valueForKeyPath:@"manager.lastName"];

この場合は、対象 Employee オブジェクト(上司)のデータが自動的に取得されます。

ここに微妙ながらも、重要なポイントがあります。なお、関係を渡り歩くために(この例では、従業員の上司を見つけるために)、関連オブジェクトを明示的に受信する必要はありません(すなわち、受信要求の作成と実行はしません)。単にキー値コーディング(あるいはアクセサメソッドを実装していれば、それら)を使用して 1 つまたは複数の対象オブジェクトを取得するだけで、Core Data によって関連オブジェクトが自動的に作成されます。たとえば、従業員の上司の上司の部署名は次のように要求することができます。

NSString *managersName = [anEmployee valueForKeyPath:@"manager.manager.department.name"];

(もちろん、これは従業員が管理階層の少なくとも 2 つ下のレベルにいるという前提です。)また、コレクション操作メソッドを使用することもできます。従業員の部署に関する給与オーバーヘッドは次のようにして見つけることができます。

NSNumber *salaryOverhead = [anEmployee valueForKeyPath:@"department.employees.@sum.salary];

多くの場合、最初の受信でオブジェクトグラフの開始ノードを取得し、その後は受信要求を実行せず、関係をたどります。

フォールトの発動

フォールトの発動は比較的高価なプロセスになるため(場合によっては、永続ストアとの間を往復する必要があります)、不必要なフォールトの発動を避けたいこともあります。以下のメソッドは、フォールトを対象にフォールトを発動させることなく、安全に呼び出すことができます。isEqual:hashsuperclassclassselfzoneisProxyisKindOfClass:isMemberOfClass:conformsToProtocol:respondsToSelector:retainreleaseautoreleaseretainCountdescriptionmanagedObjectContextentityobjectIDisInsertedisUpdatedisDeleted、および isFault

isEqual および hash はフォールトを発動しないため、管理対象オブジェクトは一般的にフォールトを発動させずにコレクションに配置することができます。ただし、コレクションオブジェクトを対象にキー値コーディングメソッドを呼び出すと、管理対象オブジェクトを対象に valueForKey: が呼び出されることがあり、結果としてフォールトが発動される場合があります。さらに、description のデフォルト実装ではフォールトは発動しませんが、カスタムの description メソッドを実装してオブジェクトの永続プロパティにアクセスすると、フォールトが発動します(ただし、description はオーバーライドしないことを強くお勧めします)。

データの確実な更新

2 つのアプリケーションで同じデータストアを使用したり、1 つのアプリケーションに複数の永続性スタックがある場合は、いずれかの管理対象オブジェクトコンテキストまたは永続オブジェクトストアの管理対象オブジェクトが、リポジトリの内容との同期を失う可能性があります。そうなった場合は、管理対象オブジェクト、そして特に永続オブジェクトストア(スナップショット)のデータを「リフレッシュ」して、データ値を最新の状態にする必要があります。

それには、編集コンテキストメソッド -refreshObject: mergeChanges: を使用します。

mergeChanges フラグが YES であれば、オブジェクトと永続ストアコーディネータで利用できるオブジェクトの状態をマージします。このフラグが NO の場合、状態をマージせずに単純にオブジェクトを再フォールトします(その結果、関連する他の管理対象オブジェクトも解放されるので、このメソッドを使用して、メモリに持ちたいオブジェクトグラフを部分的に縮小できます)。





Preliminary Last updated: Tiger




Did this document help you?
Yes: Tell us what works for you.

It’s good, but: Report typos, inaccuracies, and so forth.

It wasn’t helpful: Tell us what would have helped.
Get information on Apple products.
Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Copyright © 2007 Apple Inc.
All rights reserved. | Terms of use | Privacy Notice