【问题标题】:CoreData relationships not merging from one MOC to anotherCoreData 关系没有从一个 MOC 合并到另一个
【发布时间】:2013-01-02 13:09:12
【问题描述】:

我一直在用这个虫子把头撞到墙上。基本上关系没有正确地从一个上下文合并到另一个上下文。

假设我的模型中有两种实体类型,学生和教师。一个学生只能有一个老师,一个老师显然可以有很多学生。我在我的 xcdatamodel 类中正确设置了它。

因为我正在从服务器同步这些实体,所以我有 2 个托管对象上下文 - 一个名为 uiContext,其并发类型设置为 NSMainQueueConcurrencyType,另一个名为 backgroundContext,其并发类型设置为 @987654324 @。

我还使用[self.uiContext setParentContext:self.backgroundContext]; 设置了一个嵌套结构

这就是我正在做的事情:

1) 从服务器获取教师

2) 在backgroundContext中为它们创建托管对象

3) 拨打savebackgroundContext

4) 我监听NSManagedObjectContextDidSaveNotification,并执行以下代码:

[self.uiContext performBlock:^(void) {
   [self.uiContext mergeChangesFromContextDidSaveNotification:notif];
}];

到目前为止,这工作得很好。我的 uiContext 获得了教师管理的对象,我的 UI 也会相应地更新。

当我执行以下操作时它会崩溃:

5) 从服务器获取学生数据

6) 在backgroundContext 中为他们创建托管对象并设置学生与相应教师的关系。

7) 拨打savebackgroundContext

8) 因为我正在收听NSManagedObjectContextDidSaveNotification 通知,所以这个保存应该合并到uiContext

但是,这是我开始遇到问题的地方。即使学生对象正确地合并到uiContext 中,也没有设置教师与学生的关系。从学生到老师的关系是正确设置的,但不是相反。具体来说,[someTeacherObject.students count] == 0 但someStudentObject.teacher != nil

backgroundContext 和持久存储(已验证)中的关系设置正确。只是不在uiContext 中。

任何想法可能会发生什么?知道如何更好地调试吗?

【问题讨论】:

  • 在您的数据模型中,学生实体的teacher 关系是否与教师实体的students 关系相反?
  • 是的,设置正确。而且我相信这一定是因为数据在 backgroundContext 和持久存储中设置正确。
  • 如果是这种情况,那么[someTeacherObject.students count] == 0 和someStudentObject.teacher != nil 应该是不可能的-- 除非someStudentObject.teacher 实际上指向与您正在检查的someTeacherObject 不同的教师对象。作为反向关系,将一个设置为非零会强制另一个的计数 > 0。您确定要比较相同的实例吗?
  • 好吧,做了更多的挖掘,你是对的,看起来它们是不同的教师对象。我相信这是因为如果我登录 someTeacherObject.objectId 与 someStudentObject.teacher.objectId,objectIds 是不同的
  • 如果我的 backgroundContext 中有一个教师对象并将其合并到我的 uiContext 中,它应该具有相同的 objectId 正确吗?

标签: ios core-data merge relationship nsmanagedobjectcontext


【解决方案1】:

据我所知,一旦您为背景上下文设置了 parentContext,您就不再需要监听更改并手动合并它们。但是,您确实需要在主上下文上执行额外的saveContext: 以保存对存储的更改。

有关详细信息,请参阅此 article on multi-context Core Data 的“父/子上下文”部分。

编辑

取自那篇文章,代码如下所示:

[backgroundContext performBlock:^{
// do something that takes some time asynchronously using the bg context

   // push to parent
   NSError *error;
   if (![backgroundContext save:&error])
   {
       // handle error
   }

   // save parent to disk asynchronously
   [mainMOC performBlock:^{
        NSError *error;
        if (![mainMOC save:&error])
        {
           // handle error
        }
    }];
}];

【讨论】:

  • 我实际上是反过来的。我的 backgroundContext 是我的 uiContext 的父级(请参阅问题中的我的代码 sn-p)。
  • 所以如果我想对我的 backgroundContext 进行更改,我确实需要将对我的 backgroundContext 所做的更改合并到我的 uiContext 中
猜你喜欢
  • 2020-09-15
  • 2021-02-11
  • 1970-01-01
  • 1970-01-01
  • 2012-04-05
  • 2016-05-06
  • 2013-10-22
  • 1970-01-01
相关资源
最近更新 更多