核心数据 - 在多个线程之间共享NSManagedObjects

gos*_*vka 5 iphone core-data objective-c ios

我遇到了在多个线程中使用单个MOC的所有后果 - 我的应用程序在随机点崩溃,因为MOC是在主线程中创建的,我也用它来填充另一个线程中的DB.虽然代码是使用全局单例同步(@synchronize),但应用程序崩溃了.我读到每个线程使用一个单独的MOC会使事情变得正常,但我也读到,在线程之间共享NSManagedObjects也被认为是一种糟糕的方法.

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

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

大多数情况下,应用程序出现错误,提示我正在修改集合,同时枚举它不是真的,因为代码是同步的,而我正在迭代它没有修改发生,反之亦然 - 虽然我修改它我不迭代,我保存一旦我完成.

Mic*_*chs 8

NSManagedObjectContext每个线程使用一个.如果在线程之间进行通信,则传递NSManagedObjectID线程安全的,并从线程上下文中再次获取对象.在我的应用中,我有时甚至每个控制器使用一个上下文

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

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


Kim*_*and 5

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

有关更多信息,请参阅svena的答案: 使用NSOperationQueues的核心数据和并发