解决与多个线程,关系和指针的NSManagedObject冲突

时间:2011-02-24 02:51:09

标签: core-data conflict nsmanagedobject

通过外部线程保存一堆NSManagedObjects时发生冲突。对于初学者,我可以告诉你以下内容:

  1. 我为每个帖子使用单独的MOC。
  2. MOC共享同一个持久性商店协调员。
  3. 外部线程可能正在修改我正在保存的一条或多条记录。
  4. 好的,这样就可以了,这就是我正在做的事情。

    在我的外部线程中,我正在进行一些计算并更新一堆托管对象中的单个值。我这样做是通过我的主键查找持久存储中的对象,修改单个十进制属性,然后一次性调用一行中的保存。

    与此同时,我认为主线程正在进行一些更新。

    当我的外部线程对其托管对象上下文进行大量保存时,我会抛出一个异常,说明存在大量冲突。所有冲突似乎都围绕着每条记录上的单一关系。虽然持久存储中的托管对象和我的外部线程共享此关系的相同ObjectID,但它们不共享相同的指针。基于我所看到的,这是NSMergeConflict调试输出中对象之间唯一不同的东西。

    对我来说,为什么这两个对象与不同的指针有关系是有意义的 - 它们在不同的线程中。但是,正如我从Apple的文档中所理解的那样,首次从持久性存储中检索对象时缓存的唯一内容是全局ID。所以,有人会认为当我在外部线程MOC上运行save时,它会比较ObjectID,看到它们是相同的,并让它全部通过。

    那么,谁能告诉我为什么会发生冲突?

3 个答案:

答案 0 :(得分:2)

根据核心数据编程指南并发核心数据一章中的文档,推荐的配置是让上下文共享同一个持久性存储协调器,而不是只是同一个持久存储。

此外,如果您使用 NSManagedObjectContextDidSaveNotification 跟踪更新,则跟踪使用通知的其他线程中的更改部分会说明您发送 -mergeChangesFromContextDidSaveNotification 到主线程的上下文,以便它可以合并更改。但是如果您使用 NSManagedObjectContextDidChangeNotification 进行跟踪,则外部线程应该将修改后的对象的对象ID发送到主线程,然后主线程将 -refreshObject:mergeChanges:发送到其主线程每个修改过的对象的上下文。

实际上,您应该知道主线程是否也通过其控制器执行更新,并以相同的方式传播其更改,但方向相反。

答案 1 :(得分:0)

您需要让所有上下文从任何进行更改的上下文中侦听NSManagedObjectContextDidSaveNotification。否则,只有前端上下文将知道在后台线程上所做的更改,但后台上下文将不会知道前端线程上的更改。

因此,如果您有三个线程和三个上下文,每个线程都进行更改,则所有三个上下文必须注册来自其他两个的通知。

答案 2 :(得分:0)

不幸的是,好像这个错误实际上是由其他东西造成的 - 我在不应该的时候同时调用该操作导致错误不止一次。虽然这并没有回答关于为什么指针在冲突中很重要的初始问题,但更新我的代码以防止这种情况已经解决了我的问题。