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

Posted

技术标签:

【中文标题】核心数据 - 在多个线程之间共享 NSManagedObjects【英文标题】:Core Data - sharing NSManagedObjects among multiple threads 【发布时间】:2012-10-13 15:24:19 【问题描述】:

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

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

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

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

【问题讨论】:

【参考方案1】:

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

要管理不同的上下文,请为NSManagedObjectContextDidChangeNotification 注册一个观察者。在此通知处理中,您通过 mergeChangesFromContextDidSaveNotification: 方法将通知传递给您的每个上下文。这个方法是线程保存,让上下文更新它的状态。

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

【讨论】:

【参考方案2】:

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

在此处查看 svena 的答案以获取更多信息: Core Data and Concurrency using NSOperationQueues

【讨论】:

以上是关于核心数据 - 在多个线程之间共享 NSManagedObjects的主要内容,如果未能解决你的问题,请参考以下文章

创建 NSManagedObjectContext 以在线程中使用

多线程编程-----线程同步

java核心-多线程-线程类基础知识

python核心编程笔记----threading

Java核心技术-并发

Java核心技术 卷1 多线程