1

私は次の設定をしています:

NSManagedObjectContext *parent = [[NSManagedObjectContext alloc] 
                            initWithConcurrencyType:NSMainQueueConcurrencyType];
// other setup for parent

NSManagedObjectContext *child = [[NSManagedObjectContext alloc] 
                          initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[child setParentContext:parent];

私が欲しいのは、子が保存するたびに親を保存することです。したがって、現在、私は次のようなことをしています。

[child performBlock^{
      [child save:nil];
      [parent performBlock:^{
          [parent save:nil];
      }
}];

それは私が安全であり、コンテキスト自体のキュー内でsaveを呼び出すことです。それは必要ですか?私はただすることができます:

[child performBlock^{
     [child save:nil];
     [parent save:nil];
}];
4

2 に答える 2

2

いいえ、2番目のバリアントは使用できません。saveメインキューではなく、子コンテキストに関連付けられているキューで親コンテキストの操作を実行します。

これは、save操作がメインスレッドとは(潜在的に)異なるスレッドで実行されることを意味します。これは、管理対象オブジェクトコンテキストがスレッドセーフではないため、許可されていません。

OSXv10.7およびiOS5.0 のコアデータリリースノートの管理対象オブジェクトコンテキストの同時実行サポートも参照してください。

キューベースの同時実行タイプを2つの新しいメソッドと組み合わせて使用​​するコンテキストを使用します:performBlock:および performBlockAndWait:。... 1つの例外は、コードがメインスレッドで実行されている場合、ブロックベースのAPIを使用する代わりに、メインキュースタイルのコンテキストでメソッドを直接呼び出すことができることです。

performBlock:performBlockAndWait:コンテキストに指定されたキューでブロック操作が実行されるようにします。..。

于 2012-11-23T18:44:15.350 に答える
1

メインコンテキストを呼び出して独自のキューに保存する必要があります。親コンテキストにメインキューを使用すると、次のように実行できると思います。

[child performBlock^{
     [child save:nil];
     [parent performSelectorOnMainThread:@selectorr(save:) withObject:nil waitUntilDone:NO];
}];

このコードにより、親のmanagedObjectContxtが常にメインスレッドに保存されるようになります。また、メインコンテキストを常にメインスレッドに配置して、異なるスレッド間の同期を容易にすることをお勧めします。

于 2012-11-23T20:24:06.013 に答える