iPhone 核心数据和多线程
Posted
技术标签:
【中文标题】iPhone 核心数据和多线程【英文标题】:iPhone Core Data and Multithreading 【发布时间】:2010-08-27 04:11:05 【问题描述】:我正在开发一个 iPhone 应用程序,它通过网络传输数据并将接收到的数据保存在核心数据对象中以供以后使用。目前。它在单个线程中正常工作,但我正在努力将数据传输机制转换为在单独的工作线程中运行。
我已经阅读了关于多线程的核心数据编程指南,并且我计划为每个线程使用单独的托管对象上下文和一个单一的持久存储协调器,这似乎是 Apple 推荐的。
应用程序的主线程永远不需要创建或删除核心数据对象,而是询问工作线程。它主要是读取对象并偶尔修改它们。它还会定期要求工作线程从网络中获取新对象或现有对象的更新。
我的问题涉及我需要做些什么来支持这一点。核心数据编程的多线程部分说我可以通过传递对象 ID 在两个线程之间“传递”对象。我对我需要做什么感到有点困惑。这两个线程是否每个都有自己获取的每个对象的副本?如果是这样,它们是如何同步的?您是否应该明确地对您知道其他线程已修改的对象进行故障处理以使它们重新加载?
假设我在主线程中使用了一个对象,并且工作线程修改了它。让工作线程通知主线程该对象已被修改以便主线程可以错误地强制重新加载就足够了吗?还是会自动出错?或者也许这整个场景是一个坏主意,会导致异常?
我正在考虑通过在当前正在使用的所有对象的主线程中添加一个字典来实现这一点。当工作线程修改一个时,大概是因为它从网络获取了更新版本,我将让它向主线程发出信号,如果它当前在它正在使用的对象列表中,则主线程可以使对象出错。这听起来是个好主意,还是有必要?
【问题讨论】:
developer.apple.com/library/content/documentation/Cocoa/… 【参考方案1】:需要记住的几个关键点:
-
仅在线程之间共享对象 ID
结合使用 NSManagedObjectContextDidSave 通知和 NSManagedObjectContext 方法 mergeChangesFromContextDidSaveNotification: 或 refreshObject:mergeChanges:
花一些时间编写代码来解决合并错误(即重置对象并再次尝试合并等)
您似乎掌握了正确的基础知识,通常棘手的地方是合并两个线程中已修改的对象。在这种情况下,您必须重置要合并的对象,将其与通知线程的更改合并,然后根据需要重新应用任何本地更改。在这种情况下,有几个 API 方法可以帮助您:
-
NSManagedObject#changedValues 将为您提供所有已更改属性的字典,您可以将其存储起来以便在合并后重新应用。遍历它的键并调用 NSManagedObject#setValue:forKey: 重新应用值。
如前所述,NSManagedObjectContext#refreshObject:mergeChanges:,当您知道线程没有触及任何相同属性时,最好使用此方法。在某些情况下,这是通过设计保证的(网络线程仅更新时间戳等)。
最后,将您的处理代码封装在一个 NSOperation 中将使您可以非常轻松地控制线程本地托管对象上下文的对象生命周期以及您可能因解析而占用的任何内存。
【讨论】:
以上是关于iPhone 核心数据和多线程的主要内容,如果未能解决你的问题,请参考以下文章