在核心数据的上下文之间共享非持久对象?

Posted

技术标签:

【中文标题】在核心数据的上下文之间共享非持久对象?【英文标题】:Sharing Non-Persistent Objects Between Contexts in Core Data? 【发布时间】:2010-07-23 06:44:37 【问题描述】:

我想知道是否有办法在同一线程中运行的两个或多个NSManagedObjectContext 对象之间共享NSManagedObject

我有以下问题:我在应用程序中的所有代码共享一个主要上下文,并且为我发出的每个远程获取请求创建了几个不同的上下文。 (我创建了一个自定义类,它远程获取并将服务器中找到的所有对象插入到他自己的NSManagedObjectContext 中)。这些获取请求可能会同时运行,因为它们使用可能在不同时间结束的NSURLConnection 对象。如果同一个远程对象被不同的连接获取,我将在保存上下文并将上下文与主要对象合并时得到重复。 (即,具有相同远程 ID 但不同 objectID 的对象)。

一种可能的解决方案是在创建每个对象后立即保存(并因此保留)每个对象,但我不能这样做,因为它可能有一些关系可能仍未填充并且不会在保存操作。

我真的很期待一种方法,它允许您在上下文之间共享相同的非持久对象实例。如果有人遇到此问题并提出解决方案,我很高兴知道!

【问题讨论】:

【参考方案1】:

上下文不能通过它们的存储相互通信。但是,您可以插入带有 nil 托管对象上下文的托管对象,它将独立于任何上下文(尽管没有关系)。您可以随意传递该独立托管对象,并在需要持久保存它时将其插入上下文中。这是危险的,但有可能。

但是,如果您没有在单独的线程上运行每个连接,那么拥有多个上下文就不会获得任何好处。每个连接对象将在主线程上按顺序激活其委托。在这种情况下,您最简单的解决方案是对所有连接使用相同的委托,并让委托处理对单个上下文的插入。为防止重复,只需在 remoteID 上进行 fetch 并查看是否在为该 remoteID 插入新对象之前取回现有对象。

【讨论】:

非常感谢您的回答。这真的很有帮助。使用单个上下文的方法的唯一问题是,一旦远程获取请求之一结束,我就无法保存它,因为可能还有其他请求尚未从服务器获取某些非可选关系对象(从而取消保存操作)。我目前正在这样做,但我想避免的是等待所有获取请求都完成以保存和合并主上下文中的对象。我想这个问题没有解决方案,因为传递 nil 是不够的......【参考方案2】:

我不认为你想做的事是可能的。我的意思是,如果您想在不同的上下文之间共享更改,则必须在保存或发生更改时使用通知并合并它。但在你的情况下,我会说只使用 1 个上下文并最终保存。或者一种不太优雅的方式:将所有远程 id 临时保存在您的应用中,并在插入新的之前进行检查。在这种情况下,您可以继续使用多个上下文并在每次完成加载后保存。

【讨论】:

以上是关于在核心数据的上下文之间共享非持久对象?的主要内容,如果未能解决你的问题,请参考以下文章

核心数据重载数据库

排查核心数据死锁?

当每个线程可以处理与其他线程中的数据无关的数据时,是不是可以在线程之间重用一个共享托管对象上下文?

cuDevicePrimaryCtxRetain() 是不是用于在多个进程之间拥有持久的 CUDA 上下文对象?

在 OS X 上的 OpenGL 上下文之间共享数据(不同的版本/配置文件)

WatchKit 核心数据同步