通过外部线程保存一堆NSManagedObjects时发生冲突。对于初学者,我可以告诉你以下内容:
好的,这样就可以了,这就是我正在做的事情。
在我的外部线程中,我正在进行一些计算并更新一堆托管对象中的单个值。我这样做是通过我的主键查找持久存储中的对象,修改单个十进制属性,然后一次性调用一行中的保存。
与此同时,我认为主线程正在进行一些更新。
当我的外部线程对其托管对象上下文进行大量保存时,我会抛出一个异常,说明存在大量冲突。所有冲突似乎都围绕着每条记录上的单一关系。虽然持久存储中的托管对象和我的外部线程共享此关系的相同ObjectID,但它们不共享相同的指针。基于我所看到的,这是NSMergeConflict调试输出中对象之间唯一不同的东西。
对我来说,为什么这两个对象与不同的指针有关系是有意义的 - 它们在不同的线程中。但是,正如我从Apple的文档中所理解的那样,首次从持久性存储中检索对象时缓存的唯一内容是全局ID。所以,有人会认为当我在外部线程MOC上运行save时,它会比较ObjectID,看到它们是相同的,并让它全部通过。
那么,谁能告诉我为什么会发生冲突?
答案 0 :(得分:2)
根据核心数据编程指南的并发核心数据一章中的文档,推荐的配置是让上下文共享同一个持久性存储协调器,而不是只是同一个持久存储。
此外,如果您使用 NSManagedObjectContextDidSaveNotification 跟踪更新,则跟踪使用通知的其他线程中的更改部分会说明您发送 -mergeChangesFromContextDidSaveNotification 到主线程的上下文,以便它可以合并更改。但是如果您使用 NSManagedObjectContextDidChangeNotification 进行跟踪,则外部线程应该将修改后的对象的对象ID发送到主线程,然后主线程将 -refreshObject:mergeChanges:发送到其主线程每个修改过的对象的上下文。
实际上,您应该知道主线程是否也通过其控制器执行更新,并以相同的方式传播其更改,但方向相反。
答案 1 :(得分:0)
您需要让所有上下文从任何进行更改的上下文中侦听NSManagedObjectContextDidSaveNotification。否则,只有前端上下文将知道在后台线程上所做的更改,但后台上下文将不会知道前端线程上的更改。
因此,如果您有三个线程和三个上下文,每个线程都进行更改,则所有三个上下文必须注册来自其他两个的通知。
答案 2 :(得分:0)
不幸的是,好像这个错误实际上是由其他东西造成的 - 我在不应该的时候同时调用该操作导致错误不止一次。虽然这并没有回答关于为什么指针在冲突中很重要的初始问题,但更新我的代码以防止这种情况已经解决了我的问题。