从 CoreData 关系中获取错误实体的对象
Posted
技术标签:
【中文标题】从 CoreData 关系中获取错误实体的对象【英文标题】:Objects of wrong entity fetched from CoreData relationship 【发布时间】:2016-10-11 16:30:55 【问题描述】:我有一个相当大的 CoreData 模型,它突然表现得很奇怪。共有三个相关实体:
用户 故事 组User
有一个名为 stories
到 Story
对象的多对多关系和一个多对多关系 groups
到 Group
对象。两者也都有适当的逆。我使用 mogenerator 为所有属性和关系生成便利访问器。两者都是有序对多关系。
现在有时会发生,当我向用户对象询问其groups
(如user.groups
)时,我实际上得到了一组 NSOrdered 的 XNGStory 对象。在我观察到的少数情况下,它们与user.stories
返回的对象相同。这两个集合不一样(不同的指针),但它们的内容是(我通过在它们上调用array] valueForKeyPath:@"objectID.URIRepresentation"]
进行检查,并在两种情况下以相同的顺序获得相同的 URI)。
感觉好像我的应用程序中有某种方式将故事存储在 groups
关系中,但我检查了代码,只有与组相关的类触及 groups
关系,只有故事相关的类触及 @987654334 @-关系。两者之间也没有交互或关系,它们在应用程序的完全独立的部分中使用,所以我不知道这种数据损坏是如何发生的。
是否有任何原因可能会发生这种数据损坏?当我意外地将对象存储在错误的关系中时,我本来希望 CoreData 会抱怨。
还有一件事:到目前为止,我们只能在 ios 10 上重现它。
我们尝试过的事情:
我们首先怀疑存在内存问题(因为错误类型的对象出现在不应该出现的位置),但在启用 Address Sanitizer 和 NSZombies 的情况下运行并没有发现任何问题。此外,一旦出现问题,它会在应用重新启动时持续存在,并且使用调试器在对象中四处寻找也显示出一致(错误)的数据模型,因此错误的不仅仅是一个指针。 已停用 WAL(问题仍然存在) 在与Core Data Editor 发生崩溃后查看 sqlite 文件(包括和不包括 WAL):它显示groups
关系的组对象,所以在 sqlite 数据库级别上似乎一切都很好 -> 不知何故从文件加载时,关系会混淆。
【问题讨论】:
【参考方案1】:据我所知,这似乎是 iOS 10 的错误。
我们在使用 Core Data 的应用程序中遇到了类似的问题 - User 对象具有 Addresses(与 Address 对象)和 Friends(与其他 User 对象)的关系。
由于某些原因在iOS 10 Core Data下偶尔会选择返回Friends关系中的Address对象。
我们已经对 iOS 9 进行了回归测试,并且没有出现此问题。
Open Radar 上存在一个针对同一问题的开放错误 - 26826183。有趣的是,我们只是在 10.0.2 下才开始看到此问题,但 Radar 报告基于早期的 iOS 10 Beta。
【讨论】:
我收到来自应用程序用户的报告,称 Core Data 存在错误并且无法获取数据。两个用户都安装了 10.0.2。【参考方案2】:我们对此进行了广泛的测试,并得出结论认为这是一个 iOS 10 错误。它似乎也与我们的任何代码无关,仅与数据模型有关。我们能够使用我们的数据模型、Xcode 8 的代码生成和 iOS 10 的新 NSPersistentContainer
(在它破坏之前使用 mogenerator 和“设置 CoreData 堆栈的旧方法”)在示例项目中重新创建问题。
要重现该问题,我们执行以下操作:
-
在启动时,如果没有
User
-object,则创建一个User
-object并添加10个Group
对象并保存。
然后添加一个Story
到它,仍然在主上下文中,然后保存。
终止应用(通过 iOS 向上滑动或简单地通过在 Xcode 中按“停止”)
再次启动应用程序。启动时,获取User
对象,将Story
对象添加到stories
关系并保存。
检查背景或主上下文中的user.groups
关系。它现在包含 XNGStory
对象,尽管它应该仍然有 XNGGroup
对象。
我在示例项目中提交了一份 Radar。 OpenRadar 是here(没有示例项目,因为它包含我们的数据模型)。
问题似乎高度依赖于数据模型设置。当我们的 User
实体上的 all-but-on 关系被排序时,就会发生这种情况。如果所有都是有序的,它就不会发生,如果两个或更多是无序的,它也不会发生。
【讨论】:
以上是关于从 CoreData 关系中获取错误实体的对象的主要内容,如果未能解决你的问题,请参考以下文章
核心数据 - 在不触发错误的情况下获取对多关系的 objectID