5

我遭受了在多个线程中使用单个 MOC 的所有后果——我的应用程序在随机点崩溃,因为 MOC 是在主线程中创建的,我还使用它在另一个线程中填充数据库。尽管代码是使用全局单例同步的(@synchronize),但应用程序崩溃了。我读到为每个线程使用一个单独的 MOC 可以解决问题,但我还读到它也被认为是跨线程共享 NSManagedObjects 的不好方法。

我的用例如下: 1)我从服务器加载和解析 XML,并在解析过程中将每个新的 NSManagedObject 插入数据库中。这一切都发生在一个单独的线程中。2)从主线程,用户与从数据库读取数据的 UI 交互。

在这两个线程中,我都使用 NSManagedObjects。你会建议我如何解决这个问题?我已经多次失败了。

大多数情况下,应用程序因错误而崩溃,提示我在枚举它时正在修改一个集合,这是不正确的,因为代码是同步的,并且在我迭代它时没有修改发生,反之亦然 - 当我修改它时我不迭代并且我完成后保存。

4

2 回答 2

8

NSManagedObjectContext每个线程使用一个。如果您在线程之间进行通信,请传递NSManagedObjectID线程安全的 ,然后再次从您的线程上下文中获取对象。在我的应用程序中,有时我什至每个控制器使用一个上下文。

要管理不同的上下文,请为NSManagedObjectContextDidChangeNotification. 在此通知处理中,您通过该mergeChangesFromContextDidSaveNotification:方法将通知传递给您的每个上下文。此方法是线程保存,并使上下文更新其状态。

在此之后,您必须刷新您的视图。如果您有基于表格视图的应用程序,请查看NSFetchedResultsController. 这有助于您使用适当的动画自动更新表格。如果不使用表格视图,则必须自己实现 UI 更新。

于 2012-10-13T15:40:20.340 回答
5

如果您只支持 iOS 5 及更高版本,则不再需要处理NSManagedObjectID和合并上下文。您可以改用新的并发类型NSManagedObjectContext。然后在其中进行操作managedObjectContext:performBlock,它们将自动合并。

有关更多信息,请参阅 svena 的答案: Core Data and Concurrency using NSOperationQueues

于 2012-10-13T20:40:59.863 回答