Core data 解决具有多个线程、关系和指针的NSManagedObject冲突

Core data 解决具有多个线程、关系和指针的NSManagedObject冲突,core-data,conflict,nsmanagedobject,Core Data,Conflict,Nsmanagedobject,在通过外部线程保存大量NSManagedObject时,我遇到了冲突。首先,我可以告诉你以下几点: 我为每个线程使用单独的MOC MOC共享同一个持久存储协调器 很可能是外部线程正在修改我正在保存的一个或多个记录 好了,现在我就这么做 在我的外部线程中,我正在进行一些计算并更新一组托管对象中的单个值。我通过使用主键在持久性存储中查找对象,修改single decimal属性,然后一次调用bunch上的save来实现这一点 同时,我相信主线程正在做一些自己的更新 当我的外部线程在其托管对象上下文上

在通过外部线程保存大量NSManagedObject时,我遇到了冲突。首先,我可以告诉你以下几点:

  • 我为每个线程使用单独的MOC
  • MOC共享同一个持久存储协调器
  • 很可能是外部线程正在修改我正在保存的一个或多个记录
  • 好了,现在我就这么做

    在我的外部线程中,我正在进行一些计算并更新一组托管对象中的单个值。我通过使用主键在持久性存储中查找对象,修改single decimal属性,然后一次调用bunch上的save来实现这一点

    同时,我相信主线程正在做一些自己的更新

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

    这对我来说很有意义,为什么这两个对象与不同的指针有关系——它们在不同的线程中。然而,正如我从苹果的文档中了解到的,当第一次从持久存储中检索对象时,缓存的唯一东西是全局ID。因此,有人会认为,当我在外部线程MOC上运行save时,它会比较objectid,发现它们是相同的,然后让它们全部通过


    那么,有人能告诉我为什么会发生冲突吗?

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

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


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

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


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

    不幸的是,似乎这个bug实际上是由其他原因引起的——我多次调用导致错误的操作,而我本不应该这样做。虽然这并没有回答为什么指针在冲突中起作用的最初问题,但更新代码以防止这种情况解决了我的问题。

    感谢您的回答。我将研究如何使用持久性商店协调器-我还没有研究它。至于通知,我正在使用NSManagedObjectContextDidSaveNotification在主线程上侦听更新,并将它们合并到中。不幸的是,抛出错误的是外部线程,尽管我可以在该方向添加合并,但我想知道,当除了关系的指针(而不是ObjectID)之外似乎没有任何字段被更新时,为什么会发生冲突。我刚刚检查了-我不仅使用相同的持久存储,但是同样的持久存储协调器,所以应该没有问题。如何更新主线程上下文中的对象?正如您所说,我使用的是NSManagedObjectContextDidSaveNotification,使用的是mergeChangesFromContextDidSaveNotification。但是,错误是从外部线程触发的,这意味着主线程的更改很可能没有在外部线程中得到更新。但是,这仍然回避了一个问题:如果除了与不同指针的关系之外没有任何冲突字段,为什么会发生冲突?在更改和保存对象之前,您可能需要刷新外部线程中的对象。将其设置为带有锁的关键部分,以确保主线程不会在发生更改时对其进行更改。感谢您的帮助。我知道这可能有助于解决冲突的发生,然而,我的主要问题是为什么这两个冲突摆在首位。不幸的是,正如你在我上面的评论中所看到的,我们可能永远都不知道真正的答案。无论如何谢谢你!