核心数据:获取背景并在主线程上使用 objectWithID,性能优势?

Posted

技术标签:

【中文标题】核心数据:获取背景并在主线程上使用 objectWithID,性能优势?【英文标题】:Core Data: fetch background and using objectWithID on main thread, performance benefit? 【发布时间】:2012-08-23 08:07:39 【问题描述】:

我最近阅读了 Core Data Programming Guide,Apple 建议我们这样做

您在后台线程上获取一个托管对象上下文,并传递获取的对象 ID 对象到另一个线程。在第二个线程(通常是应用程序的主线程,这样你就可以 然后显示结果),您使用第二个上下文在具有这些对象 ID 的对象中出错(您使用 objectWithID:实例化对象)。 (此技术仅在您使用 SQLite 存储时才有用,> 因为来自二进制和 XML 存储的数据在打开时会立即读入内存。)

据我了解,在后台上下文中获取不会在主线程上下文中注册托管对象,因此从 objectWithID 返回的托管对象很可能是错误的。当我们在主线程上使用它时,我们将触发新一轮的 SQLite Store 之旅。所以 UI 可能会被屏蔽。

我错过了什么吗?有没有办法避免主线程上的 I/O 开销?

【问题讨论】:

【参考方案1】:

当您在后台执行 fetch 然后使用 objectID 在主线程上执行 fetch 时,不会听到太多声音。首先,记录将在 CoreData 缓存中,这使得主线程上的相同获取更快,其次,使用 objectID 获取比使用平均获取请求获取快得多。您通常会创建一个后台获取请求,找到您要查找的对象的 objectID,然后将这些 objectID 移动到主线程。当然,对于后台线程,您必须使用与主线程不同的 NSManagedObjectContext 实例。

我建议您观看 WWDC 2010 视频“掌握核心数据”。它涉及核心数据和多线程,解释了在后台/主线程上缓存和获取的性能。

【讨论】:

我检查了视频,仍然很困惑。您提到了“CoreData 缓存”,据我了解,托管对象上下文是一个缓存,但它是特定于线程的。所以在这里没有帮助。Apple的文档没有任何解释就提到了“行缓存”。似乎它被所有线程使用并且它是特定于持久存储的。是“CoreData Cache”吗? 是的。它是与持久存储相关的缓存,而不是托管对象上下文。 有没有关于行缓存的官方文档?你们是怎么想出来的? Apple 在他们的一些文档和视频中提到了行缓存,但他们没有提供相关文档,因为您无权访问缓存的信息。基本上,这发生在后台,当你获取数据时,你要么从缓存中获取数据,要么从持久存储中获取数据,但它的工作方式对你来说是透明的。 我不得不说苹果的文档是相当模糊的。为什么您的回答遭到反对?

以上是关于核心数据:获取背景并在主线程上使用 objectWithID,性能优势?的主要内容,如果未能解决你的问题,请参考以下文章

核心数据使用完成处理程序执行获取请求或在主线程以外的其他线程中执行

在主线程中添加的线程中读取数据的核心数据

如何在后台队列中获取对象的领域结果,然后在主线程上使用它

NSAsynchronousFetchRequest - 应该在主线程上显式更新

后台核心数据

在主线程上启动对话框等待工作线程的结果