我想获取当月的所有记录,因此我将该月份的第一个日期和该月的最后一天堆叠两个谓词.由于我使用CoreData,因此日期实际存储为NSTimeInterval.
NSCalendar *calendar = [NSCalendar currentCalendar]; //Get beginning of current month NSDateComponents *beginningOfCurrentMonthComponents = [calendar components:(NSEraCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:date]; [beginningOfCurrentMonthComponents setDay:1]; NSDate *beginningOfCurrentMonthDate = [calendar dateFromComponents:beginningOfCurrentMonthComponents]; //Set a single month to be added to the current month NSDateComponents *oneMonth = [[NSDateComponents alloc] init]; [oneMonth setMonth:1]; //determine the last day of this month NSDate *beginningOfNextMonthDate = [calendar dateByAddingComponents:oneMonth toDate:beginningOfCurrentMonthDate options:0]; NSMutableArray *parr = [NSMutableArray array]; [parr addObject:[NSPredicate predicateWithFormat:@"recordDate >= %d",[beginningOfCurrentMonthDate timeIntervalSince1970]]]; [parr addObject:[NSPredicate predicateWithFormat:@"recordDate < %d",[beginningOfNextMonthDate timeIntervalSince1970]]]; //Give me everything from beginning of this month until end of this month NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:parr]; return [allRecords filteredArrayUsingPredicate:predicate];
2013-10-25 19:09:39.702 [3556:a0b] -[__NSCFNumber timeIntervalSinceReferenceDate]: unrecognized selector sent to instance 0x8911440 2013-10-25 19:09:39.704 [3556:a0b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException',reason: '-[__NSCFNumber timeIntervalSinceReferenceDate]: unrecognized selector sent to instance 0x8911440' *** First throw call stack: ( 0 CoreFoundation 0x01aa85e4 __exceptionPreprocess + 180 1 libobjc.A.dylib 0x0182b8b6 objc_exception_throw + 44 2 CoreFoundation 0x01b45903 -[NSObject(NSObject) doesNotRecognizeSelector:] + 275 3 CoreFoundation 0x01a9890b ___forwarding___ + 1019 4 CoreFoundation 0x01a984ee _CF_forwarding_prep_0 + 14 5 CoreFoundation 0x01a7e3e3 -[NSDate compare:] + 67 6 Foundation 0x014194fe -[NSComparisonPredicateOperator performPrimitiveOperationUsingObject:andObject:] + 408 7 Foundation 0x014b03de -[NSPredicateOperator performOperationUsingObject:andObject:] + 306 8 Foundation 0x014b016c -[NSComparisonPredicate evaluateWithObject:substitutionVariables:] + 347 9 Foundation 0x014299b6 -[NSCompoundPredicateOperator evaluatePredicates:withObject:substitutionVariables:] + 240 10 Foundation 0x01429845 -[NSCompoundPredicate evaluateWithObject:substitutionVariables:] + 294 11 Foundation 0x014b0009 -[NSPredicate evaluateWithObject:] + 48 12 Foundation 0x014aff89 _filterObjectsUsingPredicate + 418 13 Foundation 0x014afd42 -[NSArray(NSPredicateSupport) filteredArrayUsingPredicate:] + 328
我也使用这个循环来表示recordDate确实存在于数组中:
for (FTRecord *r in allRecords) { NSLog(@"%f",[r recordDate]); } 2013-10-25 19:09:35.860 [3556:a0b] 1380582000.000000 2013-10-25 19:09:36.556 [3556:a0b] 1380754800.000000
解决方法
您选择“使用基本数据类型的标量属性”选项
创建托管对象子类,以便将recordDate表示为
FTRecord类中的NSTimeInterval.
创建托管对象子类,以便将recordDate表示为
FTRecord类中的NSTimeInterval.
但是在谓词“recordDate> = 123.45”中,存储了左侧
作为NSKeyPathExpression,它使用valueForKeyPath:@“recordDate”来访问属性,该属性返回一个NSDate对象.
该谓词的右侧存储为NSConstantValueExpression
引用NSNumber对象.
因此,将NSDate与NSNumber进行比较,这完全导致了NSNumber
你得到的例外.
要解决此问题,您必须将该属性与NSDate进行比较
(这是@rmaddy最初建议的):
[parr addObject:[NSPredicate predicateWithFormat:@"recordDate >= %@",beginningOfCurrentMonthDate]]; [parr addObject:[NSPredicate predicateWithFormat:@"recordDate < %@",beginningOfNextMonthDate]]; NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:parr];
我测试了它,似乎产生了预期的结果.
但请注意,Core Data使用timeIntervalSinceReferenceDate和dateWithTimeIntervalSinceReferenceDate在标量之间进行转换值和NSDate,而不是timeIntervalSince1970.