iOS 具有 long long 值的 CoreData 谓词不够精确

iOS Predicate for CoreData with long long values were not precise enough

我一直在构建的这个应用程序在 iPad 上运行,我一直在使用 XCode 6.1.1 在 iOS8.1 上测试它。我遇到了一个问题,我尝试通过比较以毫秒为单位的记录日期来提取记录。记录使用 CoreData 存储。

一条记录的firstDate声明如下

record.firstDate = [NSNumber numberWithLongLong:1423288915464];

firstDate在记录的.h文件中是这样声明的:

@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
...

以前我在另一个应用程序 iPhone 6 iOS8.1 使用 XCode 6.1.1 时也遇到过类似的问题。我能够通过为 long long 值声明带有 %lld 的谓词来解决它。但是,当我使用相同的代码时,它在 iPad 上失败了。有谁知道我做错了什么?提前致谢!

编辑 1:解决方法
我有一个解决方法(虽然效率不高)。如果有人想知道,这是我提取记录后的代码片段:

NSMutableArray* validRecords = [[NSMutableArray alloc] init];

for(Record* record in results) {
    if([record.firstDate longLongValue] >= [prevStartMillis longLongValue] && [record.firstDate longLongValue] <= [prevEndMillis longLongValue])
        [validRecords addObject:record];
}   

看起来像是它的有符号和无符号值问题。 您可以使用 %llu 并检查它是否有效。

解决方案是在我检索记录后使用 if 语句检查日期(请参阅问题中的编辑 1)

您不必像以前那样从 NSNumber 中提取 long。 您可以显式使用 NSNumber 对象来创建 predicate

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
...

所以现在很容易注意到这个数字 'a bit' 更小以满足您的条件