我们一直在尝试调试Core Data多上下文/线程问题,其中将Core Data保存通知合并到我们的主线程NSManagedObjectContext
中偶尔会使应用程序崩溃。这导致约2%的应用会话崩溃,我们对如何解决这个问题感到茫然。我们非常感谢任何可能导致此次崩溃的指导或一般性建议。
我们有一个核心数据设置,如下所示:
N.B。这是从[MagicalRecord setupAutoMigratingCoreDataStack]创建的Magical Record v2.3中的默认核心数据堆栈
这是我们的应用崩溃的情况:
NSManagedObject
s(一些新实体,一些更新的实体)
NSManagedObjectContextDidSaveNotification
由Core Data广播。主队列上的默认上下文会观察到此情况,并使用主线程上的mergeChangesFromContextDidSaveNotification:
更改调用NSDictionary
。objectID
被发送到无效对象时很可能崩溃(很可能NSManagedObject
已被解除分配)。 这发生在NSManagedObjectContext
mergeChangesFromContextDidSaveNotification:
的私人实施中,所以我们不可能看到这里出了什么问题;在这一点上,我们只能说出一个应该存在的对象。
这仅发生在Core Data保存的一小部分上,表明这可能不是我们的Core Data→API堆栈的根本缺陷。此外,没有迹象表明上下文更改中的更改(插入/更新/删除)的大小或类型对崩溃的可能性有任何影响。
答案 0 :(得分:4)
NSManagedObjectContextDidSaveNotification
的文档说:
"您可以将通知对象传递给另一个线程上的mergeChangesFromContextDidSaveNotification:
,但是您不能直接在另一个线程上使用用户信息字典中的托管对象。有关更多详细信息,请参阅“核心数据编程指南”中的“与核心数据的并发”。"
也许这就是问题所在?我会确保你从通知中得到的对象是在Root发布的同一个线程上的默认上下文中保存的。
答案 1 :(得分:3)
自从这个问题发布以来已经有一段时间了,在重新发现之后,我想为了找到这个帖子的其他人回答我自己的问题。
在我的情况下,我已经从通过NSManagedObjectContexts
更新的兄弟NSManagedObjectContextDidSaveNotification
迁移了大量代码库。然而,问题与此无关,即使这确实暴露了这个问题。
真正的原因是代码的旧部分,由以前的工程师设置,在NSManagedObject
s上设置了KVO及其属性。据了解,核心数据实体上的KVO实际上是一个非常糟糕的主意。
更确切地说,当KVO在实体上设置并且该对象上的对象或关系的目标从NSPersistentStore
中删除时,似乎发生了这种情况。第二个条件似乎不是唯一问题的原因,但在我的情况下肯定是一个非常突出的原因。
课程学到了:
答案 2 :(得分:2)