什么可能导致mergeChangesFromContextDidSaveNotification不合并/无效已更新的对象?

时间:2011-05-09 19:09:16

标签: iphone ios core-data nsmanagedobjectcontext

[编辑:问题的简化版]

  1. mainMOC是主要的托管对象上下文

  2. editorMOC是在editorViewController中使用撤消管理器创建的托管对象上下文,因此用户可以编辑单个托管对象

  3. 保存editorMOC后,
  4. mainMOC刷新NSManagedObjectContextDidSaveNotification

  5. 的通知处理程序中更新的托管对象
  6. 在保存处理程序中,如果我使用[mainMOC refreshObject:obj mergeChanges:YES],则对象的更新不会反映在mainMOC后刷新中。如果我使用[mainMOC refreshObject:obj mergeChanges:NO],则对象无效,并且在下一个故障时,更改将反映在从商店加载的数据中。

  7. 问题:为什么在指定mergeChanges:YES时对象不会反映更新?

    [原始问题]

    我有一个基于核心数据的应用程序,具有多个托管对象上下文。该应用程序是复杂和专有的,所以我不能直接从应用程序共享代码。我创建了一个简单的测试应用程序,试图重现我的问题,但测试应用程序没有出现问题。我无法在实现之间找到逻辑差异。我为没有发布示例代码而道歉,我相信我在下面解释了实现。如果问题不明确,请在评论中提出,我会尽力澄清。

    这是我的情况。下面描述的所有内容都在主线程上运行。

    1. 该应用程序有一个名为mainMOC的主要托管对象上下文,可在主线程上访问,并与NSFetchedResultsControllers一起使用,以在各种表视图中显示数据。

    2. 我有一个名为EditorViewController的视图控制器,它允许编辑特定实体的现有对象。此视图控制器使用具有撤消管理器的相同持久性存储协调器创建其自己的托管对象上下文editorMOC,以便在解除编辑器时可以回滚或保存更改。

    3. EditorViewController正在观察NSManagedObjectContextDidSaveNotification。发生此通知时,通知处理程序会调用[_mainMOC mergeChangesFromContextDidSaveNotification:notification]editorMOC中的更改合并到mainMOC

    4. 使用NSFetchedResultsController的表视图控制器正在处理控制器委托消息。

    5. 我已经添加了NSLog输出来查看上述所有步骤中发生的情况,并且我已经验证了以下内容:

      • 我可以看到对象已被修改并保存在编辑器中。
      • 我可以看到调用NSManagedObjectContextDidSaveNotification并且包含更新的对象。
      • 我可以看到获取的结果控制器正在接收controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:协议消息。
      • 我可以看到mainMOC 反映更新,并且mergeChangesFromContextDidSaveNotification:未更新更新的对象。
      • 如果我退出并重新启动应用程序,则会提交更新

      作为参考,我的主应用程序和测试应用程序都实现了上述功能,但测试应用程序显示正确合并的更新,主应用程序没有。

      我正在寻找有关导致mergeChangesFromContextDidSaveNotification:无法成功合并和/或使更新的对象无效的建议。

      谢谢!

4 个答案:

答案 0 :(得分:2)

获取的结果控制器未收到controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:委托消息。相反,它会将其发送给委托,以响应上下文中的更改。如果正在发送该委托消息并且确实包含正确的对象,则主上下文会知道这些更改。

如果是这样,那么您的错误很可能出现在连接获取结果控制器和tableview的代码中。有些东西阻止对象正确显示。

答案 1 :(得分:2)

我遇到的问题导致mergeChangesFromContextDidSaveNotification无效,我为每个新的NSManagedObjectContext创建了一个新的NSPersistentStoreCoordinator。当我在所有MOC之间共享NSPersistentStoreCoordinator时,mergeChangesFromContextDidSaveNotification完美地工作。另外,确保在拥有MOC的线程上调用mergeChangesFromContextDidSaveNotification。

根据我的研究,在线程之间共享NSPersistentStoreCoordinator以与NSManagedObjectContext一起使用是安全的。 NSManagedObjectContext将根据需要锁定持久存储。

答案 2 :(得分:0)

一个可能的答案:你有第三个你不知道的MOC /忘记了。 (这发生在我身上。)

我有

  1. mainMOC
  2. editorMOC
  3. viewerMOC由于意外误导的子类化而产生 - 它应该是在看主要的MOC,而是创建自己的并看着一个冻结状态。 “检查编辑”关系正朝着另一个方向发展,因为在这种情况下,它有望成为“编辑”。
  4. 通知正确调用回调,数据正在合并到主MOC中(我可以判断,因为重新启动时数据是正确的)
  5. 注意:不需要refreshObject:mergeChanges:。这也是我尝试过的,当它不起作用时,但通知的合并应该为你处理所有的对象。

    - (void)twinStackUpdated:(NSNotification *)notification {
      [[self managedObjectContext] mergeChangesFromContextDidSaveNotification:notification];
    }
    

    不确定这是你的问题,但它可能是某些人,所以就是这样。

答案 3 :(得分:0)

为了接受某些事情,即使我没有明确的解决方案,这就是我为解决这个问题而采取的措施,问题似乎已得到解决。

我认为这是NSFetchedResultsController的缓存问题。我已经简化了这段代码,并确保每个NSFetchedResultsController都使用它自己的缓存。我已经能够删除对'refreshObject'的调用,事情似乎正常。