4

多数の管理対象オブジェクトを作成して、バックグラウンドキューからCoreDataに追加しています。私の理解では、バックグラウンドスレッドからコンテキストにアクセスできなかったため、performBlockを使用して、コンテキストが作成されたのと同じキューにコアデータを追加するようにスケジュールしていました。これは問題なく動作します...

私の質問は、テスト中に[moc performBlock:^{ ... }];、アプリケーションを削除しても期待どおりに機能することに気づきました(おそらく数分の1秒速くなります)performBlock?私はそうしていると思いますが、(今のところ:)スレッドセーフではない方法で機能しているので、理解に欠陥がないことを確認したかっただけです。

dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_async(backgroundQueue, ^{ 
    // GET DATA
    // PROCESS DATA
    NSManagedObjectContext *context = [[self managedDocument] managedObjectContext];
    [moc performBlock:^{
          // ADD TO CORE DATA
          [Core createRodInContext:context withDictionary:fuelRodDictionary];
     }];

});

編集: createRodInContextの実装を追加しました...

+ (Rod *)createRodInContext:(NSManagedObjectContext *)context withDictionary:(NSDictionary *)dictionary {

    // CREATE
    Rod *rod = [NSEntityDescription insertNewObjectForEntityForName:@"Rod" inManagedObjectContext:context];

    // POPULATE
    [neo setDataCode:[dictionary objectForKey:@"dataCode"]];
    [neo setDataName:[dictionary objectForKey:@"dataName"]];
    [neo setDataReference:[dictionary objectForKey:@"dataReference"]];
    ...
    return rod;
}
4

1 に答える 1

5

バックグラウンドスレッドでは、メインの管理対象オブジェクトコンテキストに管理対象オブジェクトを挿入(および入力)するために使用する必要があります。 [moc performBlock:^{ ... }]

省略とperformBlockは、別のスレッド(バックグラウンドキューに関連付けられている)でも管理対象オブジェクトコンテキスト(メインスレッドで作成された)を使用することを意味します。

これは偶然に機能する可能性がありますが、メインスレッドがバックグラウンドスレッドと同じ瞬間にMOCにアクセスするとすぐに、(すでに述べたように)MOCはスレッドセーフではないため、結果は予測できません。

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

閉じ込め(NSConfinementConcurrencyType)。

これがデフォルトです。コンテキストは、それを作成したスレッド以外のスレッドでは使用されないことを約束します。

ただし、他の同時実行タイプ(プライベートキュー、メインキュー)の場合も、コードがMOCに関連付けられたキューで既に実行されていない限り、常にperformBlock(または)を使用する必要があります。performBlockAndWait

于 2012-11-25T18:36:20.537 に答える