获取未保存数据时的奇怪核心数据行为

Posted

技术标签:

【中文标题】获取未保存数据时的奇怪核心数据行为【英文标题】:Bizarre Core Data behavior when fetching unsaved data 【发布时间】:2012-05-06 20:24:09 【问题描述】:

我有一个循环数据的核心数据导入器,并在导入过程中忽略重复记录。

但我发现我的 NSFetchRequest 与最近存储但尚未保存的记录不匹配。而且我看到看似相同的查询提供了不同的意外结果。

例如,在我的测试中,我发现这个查询匹配并返回结果:

fetchTest.predicate = [NSPredicate predicateWithFormat:@"%K = 3882", @"intEmployee_id"];

但这个看似相同的却没有:

fetchTest.predicate = [NSPredicate predicateWithFormat:@"%K = %@", @"intEmployee_id", @"3882"];

但是 - 在上下文保存到持久存储后,它们都匹配相同。

Apple 的文档说,默认情况下 fetches 应该针对待处理的更改工作,而且我确实遵守了 [fetchTest includesPendingChanges] = YES。

你知道这里到底发生了什么吗?这两个 fetch 怎么可能返回不同的结果?

【问题讨论】:

【参考方案1】:

也许员工 ID 不是字符串而是数字?那么谓词应该是:

[NSPredicate predicateWithFormat:@"%K = %@", @"intEmployee_id",
                                             [NSNumber numberWithInt:3882]];

这意味着不稳定的行为来自混合类型。它仍然以某种方式工作,即使不规律,因为在 SQLite 文档中它说 SQLite 在物理存储数据时实际上并没有真正区分类型。

请参阅 SQLite 网站上的 Distinctive Features of SQLite,标题为 Manifest Typing

【讨论】:

我想你可能正在做一些事情......我习惯了 SQLite 不按类型区分,到目前为止,我所有的核心数据实验都没有问题,即使从字符串中组装一个谓词下面的数据字段是一个数字。 那一定是它。 Core Data 有意隐藏了数据库层。您预期的行为是不可预测的。查询 ID 的正确方法是上面的代码。试试看,如果它解决了问题,请告诉我。【参考方案2】:

这些实际上不会评估为相同的值。

[NSPredicate predicateWithFormat:@"%K = 3882", @"intEmployee_id"]

计算为 intEmployee_id = 3882

[NSPredicate predicateWithFormat:@"%K = %@", @"intEmployee_id", @"3882"]

评估为intEmployee_id = "3882"

尝试使用数字而不是字符串作为 id。

【讨论】:

确实 - 我注意到它们对这两个不同的查询字符串求值,但是在数据库保存到持久存储之后它们的执行相同,但之前不是。 我会将此作为一个错误提交给 Apple,因为它们在保存之前和之后应该具有相同的行为......即使它们 不同,他们可能应该评估一样。 太棒了!收到回复后请更新。同时使用 NSNumber 是否有效?

以上是关于获取未保存数据时的奇怪核心数据行为的主要内容,如果未能解决你的问题,请参考以下文章

核心数据:NSManagedObjectContext 未保存/获取请求失败,直到应用退出和重新启动

通过 '*this' 传递副本时的奇怪行为

将数据插入核心数据时的奇怪行为

核心数据:使用延迟实例化时的奇怪错误行为

核心数据未保存在分发版本中

保存核心数据中断获取请求