核心数据订购一对多关系,从后台线程中保存多个上下文中的新对象

时间:2017-07-07 15:14:58

标签: ios macos core-data

我在徒步旅行应用程序中使用Core Data。我的数据中有一个有序的一对多关系,用于跟踪中的坐标。我使用后台线程来同步数据,我使用带有NSManagedObjectContext的子NSPrivateQueueConcurrencyType作为后台线程。最好的我可以从关于核心数据和线程的Apple文档中看出,我已经正确设置了我在线程中使用NSManagedObjectContext的方式。这是我遇到的问题。

  1. 在后台,同步过程会拉下路径的新坐标,并更新子项上下文中路径的坐标。
  2. 在主线程上,用户通过跟踪更多内容来更改跟踪。这些新坐标使用NSMainQueueConcurrencyType保存到父上下文。
  3. 所以现在主线程上下文有新坐标,同步线程上下文有新坐标。
  4. 同步线程然后保存其上下文,坐标保存到父上下文。
  5. 然后主线程保存其上下文。保存主上下文中的新坐标,并将它们添加到有序的一对多关系中。它们不会保存在有序关系中的正确位置。
  6. 这使得小道“跳了起来”。看到屏幕截图中的黑色小径。
  7. 这似乎是Core Data正在做的事情。它没有删除任何新对象,它们都被添加到关系中。但是,在这种情况下,我想从上下文中的一个中获取一组坐标,而不是将它们合并在一起。我找不到办法做到这一点。我现在解决这个问题的方法是将路径的对象id和所有坐标传递给主线程并将它们保存在那里。我不想在主线程上做这个工作,这是一个彻头彻尾的黑客。有谁知道更好的解决方案?

    enter image description here

1 个答案:

答案 0 :(得分:0)

问题类别
在客户端和服务器之间同步有序的对象集合。

订单损坏
所描述的设置可能会导致coordinates属性发生冲突。请考虑以下场景(该表代表有序的坐标集合):

子上下文开始同步。它获取Track及其坐标。因此,它看到与父上下文相同的有序集
家长:[c1, c2]
孩子:[c1, c2]

子上下文从服务器接收新坐标
家长:[c1, c2]
孩子:[c1, c2, c3]

父上下文收到一个新坐标
家长:[c1, c2, c4]
孩子:[c1, c2, c3]

如果保存子上下文,则坐标顺序不明确 它可以是[c1, c2, c3, c4][c1, c2, c4, c3],如果没有更多信息,则无法做出决定。

我测试了这种情况,遗憾的是Core Data并未将此报告为错误。它只是将子上下文中的新对象附加到父上下文[c1, c2, c4, c3]的坐标。

提议的解决方案
使用非有序关系并扩展坐标实体以包含时间戳(NSDate)。它允许您对坐标进行排序。

使用NSFetchedResultsController观察coordinates之间的变化。它将告诉您何时添加新坐标以及索引。这应该提供足够的信息来重绘路径。

其他性能注意事项
此处描述的核心数据堆栈不是最高性能的选项。有关详细信息,请参阅this article