mergeChangesFromContextDidSaveNotification上的EXC_BAD_ACCESS

JCo*_*way 18 core-data objective-c nsmanagedobjectcontext ios magicalrecord

我们一直在尝试调试Core Data多上下文/线程问题,其中将Core Data保存通知合并到我们的主线程NSManagedObjectContext中偶尔会使应用程序崩溃.这导致约2%的应用会话崩溃,我们对如何解决这个问题感到茫然.我们非常感谢任何可能导致此次崩溃的指导或一般建议.

我们有一个Core Data设置,如下所示:

核心数据堆栈 注意这是从[MagicalRecord setupAutoMigratingCoreDataStack]创建的Magical Record v2.3中的默认核心数据堆栈

这是我们的应用程序崩溃的情况:

  1. HTTP请求返回JSON
  2. NSManagedObject根节省上下文中将JSON解析为s(一些新实体,一些更新的实体)
  3. Root Saving Context保存到持久存储
  4. NSManagedObjectContextDidSaveNotification由Core Data广播.主队列上的默认上下文观察它并mergeChangesFromContextDidSaveNotification:使用NSDictionary主线程上的更改进行调用.
  5. objectID被发送到无效对象时崩溃(很可能NSManagedObject已被解除分配).

这是在私人实施中发生的,NSManagedObjectContext mergeChangesFromContextDidSaveNotification:所以我们不可能看到这里出了什么问题; 在这一点上我们只能告诉我们一个应该存在的对象.

在此输入图像描述

这仅发生在Core Data保存的一小部分上,表明这可能不是我们的Core Data→API堆栈的根本缺陷.此外,没有迹象表明上下文更改中的更改(插入/更新/删除)的大小或类型对崩溃的可能性有任何影响.

JCo*_*way 3

自从这个问题发布以来已经有一段时间了,在重新发现它之后,我想为了找到这个帖子的其他人而回答我自己的问题。

NSManagedObjectContexts在我的情况下,我已经从通过 's 更新的同级中迁移了一个大型代码库NSManagedObjectContextDidSaveNotification。然而,问题实际上与此无关,尽管这确实暴露了问题。

造成这种情况的真正原因是代码中存在较旧的部分,由以前的工程师设置,在NSManagedObjects 及其属性上设置了 KVO。事实证明,核心数据实体上的 KVO 实际上是一个非常非常糟糕的主意。

更准确地说,这种情况似乎是在实体上设置 KVO 并且该对象或该对象上的关系目标从NSPersistentStore. 第二个条件似乎不是问题的唯一原因,但在我的情况下绝对是一个非常突出的原因。

得到教训:

  1. 需要时使用获取结果控制器。KVO 不是一个方便的捷径,您不应该避免将狡猾的 Core Data KVO 代码迁移到 NSFetchedResultsControllers 或其他明智的替代方案,因为拖延只会伤害您。
  2. 多线程 Core Data 是一项困难但非常值得成为专家的技能。了解 Core Data 堆栈以及 Core Data 多线程的细微差别和局限性绝对值得所有的精神痛苦。