8

NSPrivateQueueConcurrencyTypeNSMainQueueConcurrencyTypetypesforを使用する場合NSManagedObjectContext、同じコンテキストでネストされたperformBlock呼び出しを行うのは安全ですか?

[backgroundContext performBlock:^{
   NSFetchRequest *myRequest = ...;  
   __block NSArray *result= nil;
   [backgroundContext performBlockAndWait:^{
       results = [backgroundContext executeFetchRequest:myRequest error:NULL];
   }];
}];

ばかげているように見えるかもしれませんが、executeFetchRequest呼び出しをカプセル化する多くのヘルパーメソッドを備えた既存のコードベースがあります。呼び出し元がすでにperformBlockを使用しているかどうかについて推測したくありません。例えば:

-(void)updateObjects:(BOOL)synchronous
{
    if (YES == synchronous)
        [self fetchHelper];
    else
    {
        [backgroundContext performBlock:^{
             [self fetchHelper];
        }];
    }
}

-(NSArray*)fetchHelper
{
     [self.backgroundContext performBlockAndWait:^{
         //Fetch the objects...
         [self.backgroundContext executeFetchRequest: (...)];
     }];
}

私はそれを試しました、そしてそれは働きます。しかし、私はコアデータとマルチスレッドに非常に注意することを(難しい方法で)学びました。

4

1 に答える 1

9

はい、performBlockAndWaitは再入可能です。Appleのリリースノートから直接...

Core Dataは、NSManagedObjectContextクラスの同時実行モデルを新しいオプションで形式化します。コンテキストを作成するときに、コンテキストで使用する同時実行パターンを指定できます。スレッドの制限、プライベートディスパッチキュー、またはメインディスパッチキューです。NSConfinementConcurrencyTypeオプションは、5.0より前のバージョンのiOSに存在していたのと同じ動作を提供し、デフォルトです。キューの関連付けで作成されたコンテキストにメッセージを送信する場合、コードがそのキューで(メインキュータイプの場合)まだ実行されていない場合、またはperformBlock ...呼び出しのスコープ内にある場合は、performBlock:またはperformBlockAndWait:メソッドを使用する必要があります。 (プライベートキュータイプの場合)。これらのメソッドに渡されるブロック内で、NSManagedObjectContextのメソッドを自由に使用できます。PerformBlockAndWait:メソッドはAPIの再入可能性をサポートします。PerformBlock:メソッドには自動解放プールが含まれており、完了時にprocessPendingChangesメソッドを呼び出します。

于 2012-05-08T15:20:18.710 に答える