【问题标题】:Using Core Data using multithreading and notifications使用多线程和通知使用 Core Data
【发布时间】:2010-11-28 12:14:04
【问题描述】:

这里还有一个关于 Core Data 和多线程的问题:

我正在 iPhone 上编写一个应用程序,它从 Internet 检索 XML 数据,在后台线程中解析它(使用 NSXMLparser),并使用它自己的 NSManagedObjectContext 将数据保存在 Core Data 中。我有一个类 - 我们称之为 DataRetriever - 为我做这件事。

有不同的 UIViewControllers 然后检索数据以将其显示在各自的 UITableViews 中,当然这发生在使用 NSFetchedResultsControllers 和用于读取的单个托管对象上下文的主线程上。

我已经阅读了this question 的答案,它告诉我需要在后台线程上注册 NSManagedObjectDidSaveNotifications(我想这将由 DataRetriever 类完成),然后在读取上下文中调用 mergeChangesFromContextDidSaveNotification 方法从主线程上的那个类。我认为,这完全是线程不安全的。不过,我可能以错误的方式解释了这一点。

我还阅读了 Apple 关于该主题的文档 this part使用通知跟踪其他线程中的更改),它告诉我只需注册 NSManagedObjectDidSaveNotifications 来自 em> 阅读上下文 in 视图控制器 on 主线程,然后它必须调用 mergeChangesFromContextDidSaveNotification 来更新其阅读上下文。

我接受了 Apple 的建议:我现在让我的视图控制器使用读取托管对象上下文作为通知源在主线程上将自己注册到 NSManagedObjectDidSaveNotifications。在编写上下文中执行此操作可能不是线程安全的,Apple 的文档对此也不是很具体。

结果:没有崩溃,但我也没有收到任何通知。

旁注:我在 Apple 的文档中读到通知不会自动传播到其他线程,而且我什至可能正在侦听来自错误上下文的通知,但是为什么 Apple 告诉我这样做呢?

非常感谢任何帮助。

-- 编辑--

为了清楚起见,我正在注册来自特定 NSManagedObjectContext 的通知,Apple 的文档特别指出 (here) 某些系统框架可能会使用 Core Data 本身的实例,所以如果我不指定来源,我可能会收到来自与我无关的上下文的通知。不过,我之前提到的文档并没有说明这一点。欢迎任何关于此设计选择的 cmets。

【问题讨论】:

标签: multithreading core-data notifications


【解决方案1】:

UI 在主线程上运行,因此您希望在另一个线程上完成任何可能使 UI 陷入困境的密集处理。您让主线程中的上下文监听通知,因为主线程上下文通常是唯一需要更新自身的上下文,因为其他线程中的其他上下文发生了变化。

所有这些都是线程安全的,因为只要一个或多个上下文仍在使用数据,就不会从持久存储中删除数据。因此,如果上下文 A 有一个包含数据的对象,而上下文 B 删除了另一个表示相同数据的对象,则上下文 A 中的对象保持活动状态,直到上下文 A 调用合并。

基本上,每个上下文都在自己的小世界中运行,直到您调用合并。 Core Data 不会出现通常困扰基于线程的数据操作的竞争条件。

【讨论】:

  • 那么,基本上你的意思是,我现在的做法是对的吗?因为它不工作。我还尝试将我的视图控制器(在它们各自的 -ViewDidLoad 方法中)注册到来自写作上下文的通知。但是在主线程上。这会在随机点使我的应用程序崩溃(我想这并不奇怪,但我不知道该怎么办)。我可以尝试在后台线程上进行注册,这是一个选择吗?请清楚我做错了什么以及我做对了什么。
  • 听起来你做事正确。毕竟大多数人都使用苹果推荐的模式。如果没有更多细节,我无法告诉你想要导致崩溃。您可能想发布一个新问题,详细说明崩溃发生的确切位置。
猜你喜欢
  • 2010-11-30
  • 2011-01-09
  • 1970-01-01
  • 1970-01-01
  • 2018-06-24
  • 1970-01-01
  • 1970-01-01
  • 2014-02-21
  • 1970-01-01
相关资源
最近更新 更多