核心数据的生产者消费者问题

Posted

技术标签:

【中文标题】核心数据的生产者消费者问题【英文标题】:Producer Consumer Issue with Core Data 【发布时间】:2009-05-23 19:37:07 【问题描述】:

我有一个核心数据应用程序。在生产者线程中,我从 Web 服务中提取数据并将其存储在我的对象中并调用 save。 我的消费者对象是一个显示相同的表视图控制器。 但是,应用程序崩溃了,我得到了 NSFetchedResultsController 错误:应在部分(null)中找到对象(实体:FeedEntry;id:0xf46f40;数据:)以进行删除

在控制台上。当我调试它时,一切正常。所以我明白这就像一个种族问题。

这些问题是如何解决的?使用核心数据设计生产者-消费者应用程序的最佳方式是什么?

【问题讨论】:

【参考方案1】:

如果您的目标是 Leopard 或更高版本,Apple 让事情变得更容易。

在您的生产者线程中创建一个与您的主线程中的 MOC 具有相同 PSC 的 MOC。您可以在此线程中从您的网络服务中提取对象,创建新对象,然后照常保存。

在您的消费者线程中,将您的控制器添加为 NSManagedObjectContextDidSaveNotification 的观察者。您的回调应该类似于:

- (void) managedObjectContextDidSave:(NSNotification *)notification

  NSManagedObjectContext *managedObjectContext = [notification object];
  if(managedObjectContext != self.managedObjectContext)
    [self.managedObjectContext mergeChangesFromContextDidSaveNotification:notification];

这样保存在生产者线程中的对象会自动拉到你的消费者线程中。

【讨论】:

谢谢 sbooth...您的回答很完美...对于其他人,要订阅 NSManagedObjectContextDidSaveNotification,请添加以下代码... [[NSNotificationCenter defaultCenter] addObserver:appDelegate selector:@selector(managedObjectContextDidSave :) 名称:NSManagedObjectContextDidSaveNotification 对象:self.managedObjectContext]; @Mugunth Kumar,因为他正在检查它是哪个上下文,你可能应该为对象参数传递 nil,你不想观察为 bg 线程而不是应用程序委托的上下文创建的新上下文。 正是我想要的。谢谢。【参考方案2】:

Core Data 通常不是线程安全的。我的偏好是在后台线程上做最少的工作,并在您从 Web 服务中检索到创建核心数据实体所需的数据后将其传递给主线程。但是,请查看this document。如果需要,有一些跨线程使用 Core Data 的策略。

【讨论】:

“核心数据通常不是线程安全的”相当具有误导性。如果您为每个线程(或每个操作;上下文非常轻量级)创建一个上下文,那么 Core Data 框架的其余部分会处理几乎所有其他事情(您所要做的就是如上所述处理 NSManagedObjectContextDidSaveNotifications)。 我同意,这非常具有误导性。

以上是关于核心数据的生产者消费者问题的主要内容,如果未能解决你的问题,请参考以下文章

核心数据中的 mach_msg_trap

kafka生产者和消费者的具体交互以及核心参数详解

多线程核心点

python多线程编程-queue模块和生产者-消费者问题

ArrayBlockingQueue核心源码解读

kafka核心概念介绍