NSPredicate BETWEEN 与 NSDate 导致 -[__NSDate ConstantValue]:无法识别的选择器发送到实例 0x1e7ff0
我正在尝试从两个日期之间具有 startTime 的核心数据记录中获取数据。
这是我的代码:
NSDate *today = [NSDate date];
NSDate *distantFuture = [NSDate distantFuture];
// Create the predicate
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"startTime BETWEEN %@", [NSArray arrayWithObjects:today, distantFuture, nil]];
NSLog(@"today: %@, distantFuture: %@", today, distantFuture);
NSLog(@"predicate: %@", predicate);
// Add the predicate to the fetchRequest
[[[self fetchedResultsController] fetchRequest] setPredicate:predicate];
NSError *error;
if (![[self fetchedResultsController] performFetch:&error])
{
// Update to handle the error appropriately.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
exit(-1); // Fail
}
这是控制台输出:
2011-03-11 02:00:03.166 TestApp[2668:307] today: 2011-03-11 01:00:03 AM +0000, distantFuture: 4001-01-01 12:00:00 AM +0000
2011-03-11 02:00:03.174 TestApp[2668:307] predicate: startTime BETWEEN {2011-03-11 01:00:03 AM +0000, 4001-01-01 12:00:00 AM +0000}
2011-03-11 02:00:03.180 TestApp[2668:307] -[__NSDate constantValue]: unrecognized selector sent to instance 0x1e7ff0
2011-03-11 02:00:03.198 TestApp[2668:307] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSDate constantValue]: unrecognized selector sent to instance 0x1e7ff0'
*** Call stack at first throw:
(
0 CoreFoundation 0x314d0987 __exceptionPreprocess + 114
1 libobjc.A.dylib 0x319a149d objc_exception_throw + 24
2 CoreFoundation 0x314d2133 -[NSObject(NSObject) doesNotRecognizeSelector:] + 102
3 CoreFoundation 0x31479aa9 ___forwarding___ + 508
4 CoreFoundation 0x31479860 _CF_forwarding_prep_0 + 48
5 CoreData 0x352ed973 -[NSSQLSimpleWhereIntermediate _generateSQLBetweenStringInContext:] + 766
6 CoreData 0x35244fff -[NSSQLSimpleWhereIntermediate generateSQLStringInContext:] + 502
7 CoreData 0x35244647 -[NSSQLFetchIntermediate generateSQLStringInContext:] + 74
8 CoreData 0x352e42b3 -[NSSQLGenerator newSQLStatementForFetchRequest:ignoreInheritance:countOnly:nestingLevel:] + 234
9 CoreData 0x352414ab -[NSSQLAdapter _newSelectStatementWithFetchRequest:ignoreInheritance:] + 378
10 CoreData 0x35241329 -[NSSQLAdapter newSelectStatementWithFetchRequest:] + 16
11 CoreData 0x35241205 -[NSSQLCore newRowsForFetchPlan:] + 288
12 CoreData 0x35240531 -[NSSQLCore objectsForFetchRequest:inContext:] + 420
13 CoreData 0x35240151 -[NSSQLCore executeRequest:withContext:error:] + 304
14 CoreData 0x352d0295 -[NSPersistentStoreCoordinator executeRequest:withContext:error:] + 896
15 CoreData 0x3523d877 -[NSManagedObjectContext executeFetchRequest:error:] + 374
16 CoreData 0x352f541b -[NSFetchedResultsController performFetch:] + 766
17 TestApp 0x0001ac6d -[MatchesCalendarDataSource loadMatchesFrom:to:delegate:] + 268
18 TestApp 0x0001ad51 -[MatchesCalendarDataSource presentingDatesFrom:to:delegate:] + 68
19 TestApp 0x00021353 -[KalViewController reloadData] + 110
20 TestApp 0x00021b15 -[KalViewController loadView] + 452
21 UIKit 0x338dc227 -[UIViewController view] + 30
22 UIKit 0x338e8d0b -[UIViewController contentScrollView] + 22
23 UIKit 0x338e8b7b -[UINavigationController _computeAndApplyScrollContentInsetDeltaForViewController:] + 30
24 UIKit 0x338e8a79 -[UINavigationController _layoutViewController:] + 24
25 UIKit 0x338e84d3 -[UINavigationController _startTransition:fromViewController:toViewController:] + 254
26 UIKit 0x338e835f -[UINavigationController _startDeferredTransitionIfNeeded] + 182
27 UIKit 0x338e82a3 -[UINavigationController viewWillLayoutSubviews] + 14
28 UIKit 0x338e823f -[UILayoutContainerView layoutSubviews] + 138
29 UIKit 0x338b10cf -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 26
30 CoreFoundation 0x3146ebbf -[NSObject(NSObject) performSelector:withObject:] + 22
31 QuartzCore 0x30a6c685 -[CALayer layoutSublayers] + 120
32 QuartzCore 0x30a6c43d CALayerLayoutIfNeeded + 184
33 QuartzCore 0x30a6656d _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 212
34 QuartzCore 0x30a66383 _ZN2CA11Transaction6commitEv + 190
35 QuartzCore 0x30a89f9d _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 52
36 CoreFoundation 0x31460c59 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 16
37 CoreFoundation 0x31460acd __CFRunLoopDoObservers + 412
38 CoreFoundation 0x314580cb __CFRunLoopRun + 854
39 CoreFoundation 0x31457c87 CFRunLoopRunSpecific + 230
40 CoreFoundation 0x31457b8f CFRunLoopRunInMode + 58
41 GraphicsServices 0x35d664ab GSEventRunModal + 114
42 GraphicsServices 0x35d66557 GSEventRun + 62
43 UIKit 0x338d5329 -[UIApplication _run] + 412
44 UIKit 0x338d2e93 UIApplicationMain + 670
45 TestApp 0x000029d7 main + 70
46 TestApp 0x00002958 start + 52
)
terminate called after throwing an instance of 'NSException'
我还尝试了下面的谓词,它使用 >= AND <= 而不是 BETWEEN 语句(见下文)。这不会导致错误,但也不会获取任何记录!
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(startTime >= %@) AND (startTime <= %@)", today, distantFuture];
作为测试,我尝试了一个不包含 NSDate 对象的谓词,它工作得很好(见下文):
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"location.title == %@", @"Boston"];
任何帮助或建议将不胜感激。
非常感谢,马修
编辑
感谢您的帮助戴夫。
所以现在我又回到使用 <=
构造,但我获取了 0 个对象。
我只是使用 today
和 distantFuture
作为测试,以绝对确保我的 startTime 位于这些日期之间。在实际代码中,它的范围是从 fromDate
到 toDate
。
这是我的 NSPredicate:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"( ( %@ <= %K ) && ( %K <= %@ ) )", fromDate, @"startTime", @"startTime", toDate];
这是控制台输出:
predicate: CAST(336261600.000000, "NSDate") <= startTime AND startTime <= CAST(339285599.000000, "NSDate")
[sectionInfo numberOfObjects]: 0
这是核心数据中的日期(属性类型设置为日期):
startTime
---------
337249800
337309200
337318200
我不知道为什么返回 0 个对象。谁能看到我哪里出错了?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
根据 文档、
BETWEEN
运算符算作聚合表达式,并且...所以,是的,为了解决这个问题,您必须使用
>=
和<=
结构。但是,鉴于您的日期之一是
[NSDate distanceFuture]
,您根本不需要“小于”比较。您应该能够执行以下操作:According to the documentation, the
BETWEEN
operator counts as an aggregate expression, and ...So yes, in order to work around this, you must use the
>=
and<=
construction.However, given that one of your dates is
[NSDate distantFuture]
, you don't need the "less than" comparison at all. You should be able to do:也许尝试使用 AND 而不是 && (虽然你的控制台输出似乎显示它正确转换。
我刚刚发布了一个适合我的示例,请注意我的条件翻转如下:
@“(%K&gt;=%@)AND(%K&lt;=% @)"
这是完整的示例
Perhaps try using AND instead of && (although your console output seems to show it converting correctly.
I just posted an example that works for me, note that my condition is flipped like so:
@"(%K >= %@) AND (%K <= %@)"
Here is the full example