奇怪的父/子NSManagedObjectContext现象

我已经创build了两个这样的背景:

// create writer MOC _privateWriterContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; [_privateWriterContext setPersistentStoreCoordinator:_persistentStoreCoordinator]; // create main thread MOC _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; _managedObjectContext.parentContext = _privateWriterContext; 

我有一个NSFetchResultedController_managedObjectContext启动。

我知道这很奇怪,但我正在向父级添加一条logging到_privateWriterContext ,我正在saving它。

令人惊讶的是,儿童情况,所以FRC得到这个事件的通知。 为什么? 我没有reset孩子,或其他任何东西。 我以为他们是独立的实体,只要孩子的情况下不会得救。


在@pteofil文章中,我发现这一行:

当一个环境发生了变化,但没有得到保存时,它的所有后代都可以看到,但是不会看到它的祖先。

它被推送到持久性存储(通过持久性商店协调器),并且对连接到商店的所有上下文都可见。

这不应该发生。 将一个NSManagedObject('logging')添加到parentContext中,不会使子对象自动意识到这个对象。 只有当你让childContext执行一个fetch时,它才会从parentContext中获取。 要弄清楚你的情况是怎么回事,下面是一些build议:

  • 找出在childContext上执行提取的时候(当你设置它时,这是由fetchedRestultsController完成的。检查提取是在将managedObject添加到parentContext之前还是之后发生的)。
  • 在fetchedResultsController的所有四个委托callback中设置断点,以找出它调用方法的对象(并查看它是否是刚刚添加到parentContext的对象)。
  • 确保你知道你正在发送消息的上下文。

我有一个类似的方法,但不同的是:childContext是上下文是用来parsing新的数据(私有队列),当这个parsing完成时,chid调用save :. 这将把更改保存到父级,这在我的情况下是mainQueueContext。 这个调用save:会导致mainQueueContext接收所有新分析的对象,任何使用该mainQueueContext的fetchedResultsController都会调用它的新/更改/更新/删除对象的委托方法。 你也可以尝试颠倒你的孩子/父母的关系,看看它是否像文档中描述的那样工作,只是为了找出发生了什么事情。

我强烈build议避免亲子关系设置。 我们的书详细介绍了为什么他们经常导致奇怪的行为: https : //www.objc.io/books/core-data/

简短的故事:他们不像你想象的那样独立。

如果您需要多个上下文,请使用共享单个持久存储协调器的多个上下文。