performBlockAndWait:ルート管理されたオブジェクトコンテキストを同期的に保存するために一時的でないオブジェクトIDを提供しない

iOS5のリリースノートとWWDC2011のプレゼンテーションの例に従って、ルート管理されたオブジェクトコンテキストをタイプ NSPrivateQueueConcurrencyType としてセットアップしました。私は NSMainQueueConcurrencyType (デフォルトのコンテキストと呼ばれる)のタイプの子コンテキストを持っています。

子コンテキストを保存したら、ブロックAPIを使用してルートコンテキストを保存します: performBlockAndWait:

つまり、このブロックが実行された直後に、ちょうどデータストアに挿入されたすべてのオブジェクトに対して非一時的な ObjectID を取得できるはずです。

しかし、代わりに、一時的なオブジェクトIDを取得します。 performBlockAndWait: performBlock:に縮退し、asyncを実行しているかのようです。しかし、なぜ?

これはバグか、いくつかの重要な前提を欠いていますか?

関連するコードは次のとおりです。

// Setup of the root MOC:
__rootContext = [[NSManagedObjectContext alloc] 
    initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[__rootContext setPersistentStoreCoordinator:[self coordinator]];

// Setup of the child MOC; I use it as the "default" context:
__defaultContext = [[NSManagedObjectContext alloc] 
    initWithConcurrencyType:NSMainQueueConcurrencyType];
[__defaultContext setParentContext:__rootContext];

// Here's the essence of the save operation:
[__defaultContext save:&error]

// Setup a block I can invoke that does the save:
void (^rootContextSaveOperation)(void) = ^{
    NSError *rootContextError = nil;
    BOOL wasRootContextSaveSuccessful = [rootContext save:&rootContextError];
    if (!wasRootContextSaveSuccessful) { 
        NSLog(@"RPDataStore: Error saving root context."); }
    };

// Call perform block and wait with the operation:
[__rootContext performBlockAndWait:rootContextSaveOperation];

// Now when I inspect one of the objects just saved, I have this check in my unit test:
BOOL isTempID = [[user objectID] isTemporaryID];

問題は、葉MOCからルートに保存されたばかりのMOC階層の "user"オブジェクト部分に対して、残念なことに "isTempID"フラグが "YES"を示していることです。

私は、他のコンテキストで使用できる永続的なObject IDを得るために、同期を同期的に実行できると私は期待していました。

performBlockAndWait:の私の概念的な期待は間違っていますか?

もしそうなら、このMOCキュー構成と同期して保存して、一時的でないObjectIDをすぐに取得するにはどうすればよいですか?

3
あなたのコメントを答えに移してから、24時間後にそれを受け入れます。それ以外の場合は、この質問は永遠に未回答と表示されます。
追加された 著者 TechZen,
公式の開発者フォーラムで、これがバグだと分かりました。あなたが登録している人のために、このスレッドを参照してください: devforums.apple.com/thread/129303? tstart = 0
追加された 著者 idStar,
ありがとう@TechZen - 私はそれを移動し、アドバイスとして受け入れます。
追加された 著者 idStar,

1 答え

誰にとって助けになるかもしれないが、私の回避策は、それを一意に取得する管理オブジェクトのためのフェッチを構築することでした。

このフェッチをルート管理されたオブジェクトコンテキストに対して実行してから、以前に保存した管理オブジェクトの非一時オブジェクトIDを確実に取得します。私の場合は、すでに検索で使用できるキーのセットを一意に識別するためのオブジェクトを管理しています。

もう1つのオプションは、子コンテキストの初期保存の前に、コンテキスト内のすべてのオブジェクトの永続オブジェクトIDを取得することです。 NSManagedObjectContextの refreshObject:mergeChanges:を使用して、スコープ内の特定のオブジェクトの現在の参照を更新することができます。これで、子コンテキストで保存されたばかりの変更が反映されます。

Obtain permanent object IDs using NSManagedObjectContext's method obtainPermanentIDsForObjects:error:

2
追加された