【发布时间】:2012-08-18 10:42:39
【问题描述】:
我正在使用多线程来获取数据、解析数据、创建对象并存储它们。完成这一切后,我希望显示窗口。 但现在我有两个问题:
- 我遇到了僵局
- 我的屏障不能作为屏障。
我认为死锁是因为我同时在多个线程中更新 managedObjectContext。
-
所以我用 ConcurrencyType 更改了我的 managedObjectContext:
__managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; -
并为并发队列创建了一个importContext并分配了parentContext:
NSManagedObjectContext *importContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; importContext.parentContext = self.managedObjectContext; -
并将我的操作放在 importContext 的 performBlock 中:
[importContext performBlock:^{ dispatch_async(backgroundQueue, ^{ [myObject methodAWithContext:importContext]; }); dispatch_async(backgroundQueue, ^{ [myObject methodBWithContext:importContext]; }); dispatch_async(backgroundQueue, ^{ [myObject methodCWithContext:importContext]; }); dispatch_barrier_async(backgroundQueueM, ^{ // create barrier to wait for the first 3 threads to be completed. dispatch_async(dispatch_get_main_queue(), ^{ // Save the data from the importContext tot the main context on the main queue NSError *importError = nil; [importContext save:&importError]; [importContext.parentContext performBlock:^{ NSError *parentError = nil; [importContext.parentContext save:&parentError]; }]; [self.window makeKeyAndVisible]; }); }); }];
方法一: 在每种方法中,我选择对象的一个子集,删除它们,然后创建新对象并保存它。 (我认为删除比获取并检查要创建的每个对象的存在更快)。 所以: 在方法 A 中,我选择所有 AObject,删除它们并创建新的 AObject。 在方法 B 中,我选择所有 BObject,删除它们并创建新的 BObject。 在方法 C 中,我选择所有 CObject,删除它们并创建新的 CObject。
但随后我收到错误消息“NSManagedObjectContext 无法删除其他上下文中的对象”。
所以方法 2: 我删除了删除。但现在我得到了各种不同的错误...... 并且屏障不会等待其他线程被执行。
Q1:我做错了什么?
Q2:如何获得等待 3 个线程完成的屏障
Q3:如何删除/清除各个线程上的对象?
(我已经阅读了 Apple 的发行说明和文档,但我找不到关于多线程和 managedContext 组合的清晰解释。)
【问题讨论】:
标签: ios multithreading core-data concurrency grand-central-dispatch