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

时间:2015-02-10 08:30:10

标签: objective-c core-data nspredicate ios8.1 xcode6.1.1

这个应用程序我一直在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
...

之前我在使用XCode 6.1.1的iPhone 6 iOS8.1的另一款应用上遇到了类似的问题。我能够通过使用%lld为长long值声明谓词来解决它。但是,当我使用相同的代码时,它在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];
}   

3 个答案:

答案 0 :(得分:1)

您不必像{1}}那样从long中提取NSNumber。 您可以显式使用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
...

所以现在人们很容易注意到这个数字是“有点”的。较小以满足您的条件

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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