ページ

2010年6月4日金曜日

CoreData - Object ID(その4)Object ID から NSManagedObject を取得する #2

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

(前回)Cocoaの日々: CoreData - Object ID(その3)Object ID から NSManagedObject を取得する


Object ID から NSManagedObject を取得するメソッドは、前回の -[objectWithID:] を含め3つある。

クラス:NSManagedObjectContext

- (NSManagedObject *)objectWithID:(NSManagedObjectID *
- (NSManagedObject *)objectRegisteredForID:(NSManagedObjectID *)objectID
- (NSManagedObject *)existingObjectWithID:(NSManagedObjectID *)objectID error:(NSError **)error

今回はこれらの動作を比較してみる。

1. objectWithID: の動作
(1) まず Object ID に該当するオブジェクトが、NSManagedObjectContext内に登録されているかチェックする。登録されている場合は、そのオブジェクトを返す(非Fault)

(2) 登録されていない場合はPersistent Storeからフェッチする。
a) 該当レコードが存在する場合
フェッチしたオブジェクトを返す(Fault)

b) 該当レコードが存在しない場合
例外がスローされる。
(例)
CoreDataObjectID[12483:80f] An uncaught exception was raised
CoreDataObjectID[12483:80f] CoreData could not fulfill a fault for '0x226340 <x-coredata://677CA547-4D80-417A-8810-70847FB0375D/Book/p20>'
CoreDataObjectID[12483:80f] *** Terminating app due to uncaught exception 'NSObjectInaccessibleException', reason: 'CoreData could not fulfill a fault for '0x226340 <x-coredata://677CA547-4D80-417A-8810-70847FB0375D/Book/p20>''
*** Call stack at first throw:
(
 0   CoreFoundation                      0x9253bbda __raiseError + 410
 1   libobjc.A.dylib                     0x97efc509 objc_exception_throw + 56
 2   CoreData                            0x9469a00e _PFFaultHandlerLookupRow + 174
 3   CoreData                            0x94699f57 -[NSFaultHandler fulfillFault:withContext:] + 39
             :

2. objectRegisteredForID: の動作
NSManagedObjectContext内に登録されているかのみチェックする。

a) Object ID に該当するオブジェクトがNSManagedObjectContext内に登録されている場合
該当するオブジェクト(NSManagedObject)を返す(非Fault)

b) 該当レコードがNSManagedObjectContext内に登録されていない場合
nil を返す。例外はスローされない。


3. existingObjectWithID:error: の動作
このメソッドは Mac OS X v10.6 から追加された(iPhone OS では 3.0以降)。基本動作は objectWithID: と同じだがヒットしなかった時は例外はスローせず、nilを返す。また errorから原因を知ることができる。

(1) まず Object ID に該当するオブジェクトが、NSManagedObjectContext内に登録されているかチェックする。登録されている場合は、そのオブジェクトを返す(非Fault)

(2) 登録されていない場合はPersistent Storeからフェッチする。
a) 該当レコードが存在する場合
フェッチしたオブジェクトを返す(非Fault)※ここは試した時には何故か Faultにならなかった(ので、非Faultにしてある)。

b) 該当レコードが存在しない場合
nilを返す。この時、errorに原因が格納される。
(例)Error Domain=NSCocoaErrorDomain Code=133000 UserInfo=0x21e6f0 "Attempt to access an object not found in store."


サンプル:CoreDataObjectID at 2010-06-04 from xcatsan's SampleCode - GitHub
※コメントを修正することで上記3種類が試せるようになっている(かなりわかりづらいが)。

- - - -
Mac OS X v10.6 / iPhone OS 3.0 では existingObjectWithID:error: が一番使い勝手がいい。