具有长长值的 CoreData 的 iOS 谓词不够精确
Posted
技术标签:
【中文标题】具有长长值的 CoreData 的 iOS 谓词不够精确【英文标题】:iOS Predicate for CoreData with long long values were not precise enough 【发布时间】:2015-02-10 08:30:10 【问题描述】:我一直在构建的这个应用程序在 iPad 上运行,我一直在使用 XCode 6.1.1 在 ios8.1 上对其进行测试。我在尝试通过比较记录的日期(以毫秒为单位)来尝试提取记录时遇到问题。记录使用 CoreData 存储。
记录的firstDate声明如下
record.firstDate = [NSNumber numberWithLongLong:1423288915464];
在记录的.h文件中声明firstDate是这样的:
@property (nonatomic, retain) NSNumber * firstDate;
谓词是这样声明的:
NSNumber* prevStartMillis = [NSNumber numberWithLongLong:1423324800000];
NSNumber* prevEndMillis = [NSNumber numberWithLongLong:1423411199000];
NSPredicate* predicate = [NSPredicate predicateWithFormat:@"firstDate >= %lld AND firstDate < %lld", [prevStartMillis longLongValue], prevEndMillis longLongValue]];
我确实得到了一些 firstDate 在指定范围内的记录。但是,我得到了一些不属于指定范围的记录,例如以下 3 条记录:
...
FirstDate:1423288915464
FirstDate:1423282909663
FirstDate:1423286413320
...
以前我在另一个使用 XCode 6.1.1 的 iPhone 6 iOS8.1 应用程序上也遇到了类似的问题。我能够通过使用 %lld 为 long long 值声明谓词来解决它。但是,当我使用相同的代码时,它在 iPad 上失败了。有谁知道我做错了什么?提前致谢!
编辑 1:解决方法 我有一个解决方法(虽然不是很有效)。如果有人想知道,这是我提取记录后的代码 sn-p:
NSMutableArray* validRecords = [[NSMutableArray alloc] init];
for(Record* record in results)
if([record.firstDate longLongValue] >= [prevStartMillis longLongValue] && [record.firstDate longLongValue] <= [prevEndMillis longLongValue])
[validRecords addObject:record];
【问题讨论】:
【参考方案1】:您不必像您那样从NSNumber
中提取long
。
您可以显式使用 NSNumber 对象来创建谓词
NSNumber* prevStartMillis = [NSNumber numberWithLongLong:1423324800000];
NSNumber* prevEndMillis = [NSNumber numberWithLongLong:1423411199000];
NSPredicate* predicate = [NSPredicate predicateWithFormat:@"firstDate >= %@ AND firstDate < %@", prevStartMillis, prevEndMillis];
已编辑: 我再次查看了您的代码,发现您编写的数字超出了您的范围。让我们用更短的方式写下你的长数字:
NSNumber* prevStartMillis = /*14233e+8*/;
NSNumber* prevEndMillis = /*14234e+8*/;
而且这个数字超出了范围:
...
FirstDate:14232e+8
FirstDate:14232e+8
FirstDate:14232e+8
...
所以现在很容易注意到这个数字“有点”小以满足您的条件
【讨论】:
谢谢,它也可以,但仍然不能解决我遇到的问题。 嗨,我测试了你的方式,它适用于我的情况!但是,如果指定的谓词下降到毫秒,这将不起作用,例如介于 1423324800004 到 1423324800006 之间。无论如何,我认为我不会以那种精度检查记录,所以我会将你的记录标记为正确答案!【参考方案2】:看起来像它的有符号和无符号值问题。 您可以使用 %llu 并检查它是否有效。
【讨论】:
嗨,我试过了,还是一样。我放弃了,使用了 if 语句【参考方案3】:解决方案是在检索记录后使用 if 语句检查日期(请参阅问题中的编辑 1)
【讨论】:
以上是关于具有长长值的 CoreData 的 iOS 谓词不够精确的主要内容,如果未能解决你的问题,请参考以下文章
具有核心数据关系的 iOS 8 Swift NSFetchResult 谓词无法访问内部 ID
用于以任何出现顺序匹配具有多个单词的列中的字符串的 Coredata 谓词