NSPredicate BETWEEN 与 NSDate 导致 -[__NSDate ConstantValue]:无法识别的选择器发送到实例 0x1e7ff0

发布于 2024-10-21 02:46:26 字数 7513 浏览 4 评论 0 原文

我正在尝试从两个日期之间具有 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 个对象。

我只是使用 todaydistantFuture 作为测试,以绝对确保我的 startTime 位于这些日期之间。在实际代码中,它的范围是从 fromDatetoDate

这是我的 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 个对象。谁能看到我哪里出错了?

I'm trying to fetch from Core Data records that have a startTime between two dates.

Here's my code:

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
}

And here's the console output:

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'

I've also tried the predicate below, which uses >= AND <= instead of the BETWEEN statement (see below). This doesn't cause an error but neither does it fetch any records!

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(startTime >= %@) AND (startTime <= %@)", today, distantFuture];

As a test I've tried a predicate that doesn't include NSDate objects and it works fine (see below):

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"location.title == %@", @"Boston"];

Any help or advice would be much appreciated.

Many thanks, Matthew


Edit

Thanks for your help Dave.

So now I'm back to using the <= construct but I'm getting 0 objects fetched.

I was just using today and distantFuture as a test to make absolutely sure that my startTime would be between those dates. In the real code it's a range from fromDate to toDate.

Here's my NSPredicate:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"( ( %@ <= %K ) && ( %K <= %@ ) )", fromDate, @"startTime", @"startTime", toDate];

Here's the console output:

predicate: CAST(336261600.000000, "NSDate") <= startTime AND startTime <= CAST(339285599.000000, "NSDate")
[sectionInfo numberOfObjects]: 0

Here are the dates that are in Core Data (the Attribute Type is set to Date):

startTime
---------
337249800
337309200
337318200

I have no idea why 0 objects are returned. Can anyone see where I'm going wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

水中月 2024-10-28 02:46:26

根据 文档BETWEEN 运算符算作聚合表达式,并且...

Core Data 不支持聚合表达式。

所以,是的,为了解决这个问题,您必须使用 >=<= 结构。

但是,鉴于您的日期之一是 [NSDate distanceFuture],您根本不需要“小于”比较。您应该能够执行以下操作:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"startTime >= %@", [NSDate date]];

According to the documentation, the BETWEEN operator counts as an aggregate expression, and ...

Aggregate expressions are not supported by Core Data.

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:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"startTime >= %@", [NSDate date]];
云雾 2024-10-28 02:46:26

也许尝试使用 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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文