【发布时间】:2015-03-13 06:30:37
【问题描述】:
我们一直在尝试调试 Core Data 多上下文/线程问题,其中将 Core Data 保存通知合并到我们的主线程 NSManagedObjectContext 偶尔会导致应用程序崩溃。这导致我们大约 2% 的应用程序会话崩溃,我们不知道如何解决这个问题。对于可能导致此崩溃的原因,我们非常感谢任何指导或一般性建议。
我们有一个如下所示的核心数据设置:
注意这是 Magical Record v2.3 中从 [MagicalRecord setupAutoMigratingCoreDataStack] 创建的默认核心数据堆栈
这是我们的应用程序崩溃的场景:
- HTTP 请求返回 JSON
- JSON 在 Root Saving Context 上被解析为
NSManagedObjects(一些新实体,一些更新实体) - 根保存上下文保存到持久存储
-
NSManagedObjectContextDidSaveNotification由 Core Data 广播。主队列上的默认上下文会观察到这一点,并在主线程上使用NSDictionary更改调用mergeChangesFromContextDidSaveNotification:。 - 当
objectID被发送到一个无效对象(很可能NSManagedObject已被释放)时,它会崩溃。
这发生在 NSManagedObjectContext mergeChangesFromContextDidSaveNotification: 的私有实现中,所以我们不可能看到这里实际出了什么问题;在这一点上,我们只能说应该存在的对象不存在。
这只发生在一小部分 Core Data 保存中,这表明这可能不是我们的 Core Data → API 堆栈中的根本缺陷。此外,没有迹象表明上下文更改(插入/更新/删除)的大小或类型对崩溃的可能性有任何影响。
【问题讨论】:
-
这些 MOC 使用什么类型的并发?合并更改时您使用的是
performBlock:还是performBlockAndWait:? -
默认 MoC 使用主队列并发类型,Root Saving MoC 使用私有队列并发类型。与应用程序中的任何私有队列的任何交互都使用 performBlock 或 performBlockAndWait。根据 Apple 文档,我们不会通过执行块与默认上下文进行交互,但是我们会确保当我们不在主线程上时我们永远不会与它进行交互。
-
只是我的 2ct;我在按本书做所有事情时遇到过这样的问题,它是由
NSNotification对象(或其userInfo属性)的NSLog()引起的。从那以后,我只在上下文中立即执行mergeChangesFromContextDidSaveNotification:,然后是save,而不以任何其他方式接触通知。从那以后,我再也没有见过它的段错误。 -
鉴于根 MOC 位于私有队列上,是否还有其他线程的堆栈跟踪信息?它试图引用的对象是否可能是已在子 MOC 中删除(或以其他方式删除)的对象?
标签: ios objective-c core-data nsmanagedobjectcontext magicalrecord