0

Concurrency with Core Data Guideによると、バックグラウンド スレッドで NSManagedObjectContext を保存しないでください。これは、スレッドが切り離されているため、保存が完了する前にアプリが終了する可能性があるためです。

私が正しく理解している場合、それはこのようなものが間違っていることを意味します

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
    NSManagedObjectContext* tempContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    [tempContext setParentContext:[[MyDataManager sharedInstance] mainContext];
    [tempContext performBlockAndWait:^{
         //Do some processing
        NSError* error;
        [tempContext save:&error];
    }];
});

私の最初の本能は、終了時にコンテキストをメイン キューに保存することですが、managedObjectContext はスレッド セーフであるはずです。次は問題を解決するものですか、それともより良い解決策がありますか?

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
    NSManagedObjectContext* tempContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    [tempContext setParentContext:[[MyDataManager sharedInstance] mainContext];
    [tempContext performBlockAndWait:^{
        //Do some processing
    }];
    dispatch_async(dispatch_get_main_queue(), ^{
        [tempContext performBlockAndWait:^{
            NSError* error;
            [tempContext save:&error];
        }];
    });
});
4

1 に答える 1

1

初め:

最初の例では、コンテキストのブロックで実行
する必要があります。 また、バックグラウンド コンテキストを使用している場合は、ディスパッチに既に GCD を使用しているため、単にそのメソッドを呼び出すことができます。したがって、次のようになります。[context save:...]performBlockAndWait:
performBlock:

NSManagedObjectContext* tempContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[tempContext setParentContext:[[MyDataManager sharedInstance] mainContext];
[tempContext performBlock:^{
    //Do some processing
    NSError* error;
    [tempContext save:&error];
}];

第二に:

「バックグラウンド スレッドでの保存はエラーが発生しやすい」 (私が理解しているとおり)
の意味: バックグラウンドで保存できますが、アプリケーションが終了した場合 (データベースまだ有効であるか、部分保存前の状態にロールバックされる可能性があります)。
==>
バックグラウンド保存を使用する場合、保存操作が 2 つのアプリケーション実行の間に完了したと想定しないでください。

3 番目に (強調するために):また
はなしでプライベート キュー コンテキストを使用しないでperformBlock:くださいperformBlockAndWait:
==>
2 番目の例では、予期しない動作が発生します。

于 2013-10-29T05:30:18.980 に答える