核心数据中的谓词搜索会在第二次通过时导致 SIGABRT。 NSBetweenPredicateOperator类型

发布于 2024-11-03 08:10:41 字数 6661 浏览 8 评论 0原文

我在核心数据中看到了一个非常奇怪的行为。我正在搜索核心数据中的位置(数据存储类型是 SQLite)。查询是寻找特定区域内的位置对象。我将搜索实现为 Between 谓词。

NSExpression *lhs = [NSExpression expressionForKeyPath:keyPath];
NSExpression *rhs = [NSExpression expressionForVariable:@"MIN_MAX"];

NSPredicate *predicateTemplate = 
    [NSComparisonPredicate predicateWithLeftExpression:lhs       
                                       rightExpression:rhs
                                            modifier:NSDirectPredicateModifier
                                                 type:NSBetweenPredicateOperatorType
                                              options:0];

NSPredicate *predicate = [predicateTemplate predicateWithSubstitutionVariables:
                          [NSDictionary dictionaryWithObject:expressionArray forKey:@"MIN_MAX"]];

其中表达式数组是一个包含 2 个对象的数组,最小值在索引 0 中,最大值在索引 1 中。数组中的每个对象都是一个 NSConstantValueExpression,定义为:

NSExpression *ex = [NSExpression expressionForConstantValue : numberValue]

我在 NSFetchedResultsController 中使用谓词,但第一次的工作原理与我预计。最终的谓词是这样的:

NSFetchRequest:0x7394360(实体:位置;谓词:(经度 之间{-122.0767937067412, -121.7137663065599} 和纬度之间 {37.16973380897733, 37.45968675392614}); sortDescriptors: (("(名称,升序,比较:)")); 限制:20;类型: NSManagedObjectResultType; )

我得到了我想要的结果。

第二次运行此代码时(通过将第二个视图推到顶部,然后关闭该视图。这会导致视图重新加载)。系统崩溃并显示此错误消息。

-[NSConstantValueExpression比较:]:发送了无法识别的选择器 到实例 0x71bbea0 2011-04-22 10:54:11.742 Wines[13667:207] 终止应用程序 由于未捕获的异常 'NSInvalidArgumentException',原因: '-[NSConstantValueExpression 比较:]:发送了无法识别的选择器 到实例 0x71bbea0'*

有什么建议吗?

下面是完整的堆栈。

谢谢,

    *** Call stack at first throw:
(
    0   CoreFoundation                      0x02f0bb99 __exceptionPreprocess + 185
    1   libobjc.A.dylib                     0x0305b40e objc_exception_throw + 47
    2   CoreFoundation                      0x02f0d6ab -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
    3   CoreFoundation                      0x02e7d2b6 ___forwarding___ + 966
    4   CoreFoundation                      0x02e7ce72 _CF_forwarding_prep_0 + 50
    5   Foundation                          0x002dd909 -[NSBetweenPredicateOperator performPrimitiveOperationUsingObject:andObject:] + 317
    6   Foundation                          0x0020aee4 -[NSComparisonPredicate evaluateWithObject:substitutionVariables:] + 306
    7   Foundation                          0x00210ead -[NSCompoundPredicateOperator evaluatePredicates:withObject:substitutionVariables:] + 292
    8   Foundation                          0x00210d57 -[NSCompoundPredicate evaluateWithObject:substitutionVariables:] + 254
    9   Foundation                          0x0020adac -[NSPredicate evaluateWithObject:] + 49
    10  CoreData                            0x0252ae08 -[NSManagedObjectContext executeFetchRequest:error:] + 1752
    11  Wines                               0x00021b27 -[MOListViewController listFRC] + 1034
    12  Wines                               0x000bb1e8 -[MOLocationSelectableListViewController numberOfSectionsInTableView:] + 36
    13  UIKit                               0x0061849c -[UITableViewRowData(UITableViewRowDataPrivate) _updateNumSections] + 111
    14  UIKit                               0x00618228 -[UITableViewRowData invalidateAllSections] + 66
    15  UIKit                               0x004d2880 -[UITableView(_UITableViewPrivate) _updateRowData] + 113
    16  UIKit                               0x004cbe9c -[UITableView noteNumberOfRowsChanged] + 105
    17  UIKit                               0x004d853c -[UITableView reloadData] + 773
    18  UIKit                               0x004d5724 -[UITableView layoutSubviews] + 42
    19  QuartzCore                          0x02a22481 -[CALayer layoutSublayers] + 177
    20  QuartzCore                          0x02a221b1 CALayerLayoutIfNeeded + 220
    21  QuartzCore                          0x02a220bd -[CALayer layoutIfNeeded] + 111
    22  UIKit                               0x0050c94b -[UIViewController window:willAnimateRotationToInterfaceOrientation:duration:] + 567
    23  UIKit                               0x004889bd -[UIWindow _setRotatableClient:toOrientation:duration:force:] + 4159
    24  UIKit                               0x006fa67b -[UIWindowController transition:fromViewController:toViewController:target:didEndSelector:] + 768
    25  UIKit                               0x0050f10d -[UIViewController presentModalViewController:withTransition:] + 2937
    26  UIKit                               0x00508402 -[UIViewController _tryRecursivelyPresentModalViewController:withTransition:] + 134
    27  UIKit                               0x005083c6 -[UIViewController _tryRecursivelyPresentModalViewController:withTransition:] + 74
    28  UIKit                               0x0050e8e6 -[UIViewController presentModalViewController:withTransition:] + 850
    29  Wines                               0x0002d7a9 -[MOViewController didSelectToOneSelectOneAtIndexPath:] + 2195
    30  Wines                               0x0002e843 -[MOViewController tableView:didSelectRowAtIndexPath:] + 4219
    31  Wines                               0x0005544f -[MOPriceViewController tableView:didSelectRowAtIndexPath:] + 1509
    32  UIKit                               0x004d4a48 -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] + 1140
    33  UIKit                               0x004cb32e -[UITableView _userSelectRowAtIndexPath:] + 219
    34  Foundation                          0x001e021a __NSFireDelayedPerform + 441
    35  CoreFoundation                      0x02eecf73 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 19
    36  CoreFoundation                      0x02eee5b4 __CFRunLoopDoTimer + 1364
    37  CoreFoundation                      0x02e4add9 __CFRunLoopRun + 1817
    38  CoreFoundation                      0x02e4a350 CFRunLoopRunSpecific + 208
    39  CoreFoundation                      0x02e4a271 CFRunLoopRunInMode + 97
    40  GraphicsServices                    0x035bf00c GSEventRunModal + 217
    41  GraphicsServices                    0x035bf0d1 GSEventRun + 115
    42  UIKit                               0x0046faf2 UIApplicationMain + 1160
    43  Wines                               0x00002814 main + 102
    44  Wines                               0x000027a5 start + 53
)
terminate called after throwing an instance of 'NSException'
Program received signal:  “SIGABRT”.

I am seeing a really strange behavior in core data. I am doing a search for locations in core data (data store type is SQLite). The query is to look for location objects within a specific area. I am implementing the search as a between predicate.

NSExpression *lhs = [NSExpression expressionForKeyPath:keyPath];
NSExpression *rhs = [NSExpression expressionForVariable:@"MIN_MAX"];

NSPredicate *predicateTemplate = 
    [NSComparisonPredicate predicateWithLeftExpression:lhs       
                                       rightExpression:rhs
                                            modifier:NSDirectPredicateModifier
                                                 type:NSBetweenPredicateOperatorType
                                              options:0];

NSPredicate *predicate = [predicateTemplate predicateWithSubstitutionVariables:
                          [NSDictionary dictionaryWithObject:expressionArray forKey:@"MIN_MAX"]];

where expressions array is an array of 2 object, min in index 0, and max in index 1. Each object in the array is an NSConstantValueExpression, defined as :

NSExpression *ex = [NSExpression expressionForConstantValue : numberValue]

I am using the predicate in a NSFetchedResultsController, and the first time though works exactly as I expect. The final predicate is something like this:

NSFetchRequest: 0x7394360 (entity: Location; predicate: (longitude
BETWEEN {-122.0767937067412,
-121.7137663065599} AND latitude BETWEEN {37.16973380897733,
37.45968675392614} ); sortDescriptors: (("(name, ascending, compare:)"));
limit: 20; type:
NSManagedObjectResultType; )

And I get the results I want.

The second time this code is run (by pushing a second view on top, and closing that view. This causes the view to reload). The system crashes, with this error message.

-[NSConstantValueExpression compare:]: unrecognized selector sent
to instance 0x71bbea0
2011-04-22 10:54:11.742 Wines[13667:207]
Terminating app
due to uncaught exception
'NSInvalidArgumentException', reason:
'-[NSConstantValueExpression
compare:]: unrecognized selector sent
to instance 0x71bbea0'*

Any suggestions?

Full stack below.

Thanks,

    *** Call stack at first throw:
(
    0   CoreFoundation                      0x02f0bb99 __exceptionPreprocess + 185
    1   libobjc.A.dylib                     0x0305b40e objc_exception_throw + 47
    2   CoreFoundation                      0x02f0d6ab -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
    3   CoreFoundation                      0x02e7d2b6 ___forwarding___ + 966
    4   CoreFoundation                      0x02e7ce72 _CF_forwarding_prep_0 + 50
    5   Foundation                          0x002dd909 -[NSBetweenPredicateOperator performPrimitiveOperationUsingObject:andObject:] + 317
    6   Foundation                          0x0020aee4 -[NSComparisonPredicate evaluateWithObject:substitutionVariables:] + 306
    7   Foundation                          0x00210ead -[NSCompoundPredicateOperator evaluatePredicates:withObject:substitutionVariables:] + 292
    8   Foundation                          0x00210d57 -[NSCompoundPredicate evaluateWithObject:substitutionVariables:] + 254
    9   Foundation                          0x0020adac -[NSPredicate evaluateWithObject:] + 49
    10  CoreData                            0x0252ae08 -[NSManagedObjectContext executeFetchRequest:error:] + 1752
    11  Wines                               0x00021b27 -[MOListViewController listFRC] + 1034
    12  Wines                               0x000bb1e8 -[MOLocationSelectableListViewController numberOfSectionsInTableView:] + 36
    13  UIKit                               0x0061849c -[UITableViewRowData(UITableViewRowDataPrivate) _updateNumSections] + 111
    14  UIKit                               0x00618228 -[UITableViewRowData invalidateAllSections] + 66
    15  UIKit                               0x004d2880 -[UITableView(_UITableViewPrivate) _updateRowData] + 113
    16  UIKit                               0x004cbe9c -[UITableView noteNumberOfRowsChanged] + 105
    17  UIKit                               0x004d853c -[UITableView reloadData] + 773
    18  UIKit                               0x004d5724 -[UITableView layoutSubviews] + 42
    19  QuartzCore                          0x02a22481 -[CALayer layoutSublayers] + 177
    20  QuartzCore                          0x02a221b1 CALayerLayoutIfNeeded + 220
    21  QuartzCore                          0x02a220bd -[CALayer layoutIfNeeded] + 111
    22  UIKit                               0x0050c94b -[UIViewController window:willAnimateRotationToInterfaceOrientation:duration:] + 567
    23  UIKit                               0x004889bd -[UIWindow _setRotatableClient:toOrientation:duration:force:] + 4159
    24  UIKit                               0x006fa67b -[UIWindowController transition:fromViewController:toViewController:target:didEndSelector:] + 768
    25  UIKit                               0x0050f10d -[UIViewController presentModalViewController:withTransition:] + 2937
    26  UIKit                               0x00508402 -[UIViewController _tryRecursivelyPresentModalViewController:withTransition:] + 134
    27  UIKit                               0x005083c6 -[UIViewController _tryRecursivelyPresentModalViewController:withTransition:] + 74
    28  UIKit                               0x0050e8e6 -[UIViewController presentModalViewController:withTransition:] + 850
    29  Wines                               0x0002d7a9 -[MOViewController didSelectToOneSelectOneAtIndexPath:] + 2195
    30  Wines                               0x0002e843 -[MOViewController tableView:didSelectRowAtIndexPath:] + 4219
    31  Wines                               0x0005544f -[MOPriceViewController tableView:didSelectRowAtIndexPath:] + 1509
    32  UIKit                               0x004d4a48 -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] + 1140
    33  UIKit                               0x004cb32e -[UITableView _userSelectRowAtIndexPath:] + 219
    34  Foundation                          0x001e021a __NSFireDelayedPerform + 441
    35  CoreFoundation                      0x02eecf73 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 19
    36  CoreFoundation                      0x02eee5b4 __CFRunLoopDoTimer + 1364
    37  CoreFoundation                      0x02e4add9 __CFRunLoopRun + 1817
    38  CoreFoundation                      0x02e4a350 CFRunLoopRunSpecific + 208
    39  CoreFoundation                      0x02e4a271 CFRunLoopRunInMode + 97
    40  GraphicsServices                    0x035bf00c GSEventRunModal + 217
    41  GraphicsServices                    0x035bf0d1 GSEventRun + 115
    42  UIKit                               0x0046faf2 UIApplicationMain + 1160
    43  Wines                               0x00002814 main + 102
    44  Wines                               0x000027a5 start + 53
)
terminate called after throwing an instance of 'NSException'
Program received signal:  “SIGABRT”.

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

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

发布评论

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

评论(1

无人接听 2024-11-10 08:10:41

开始吧...

BETWEEN 操作是聚合操作,而 Core Data 不支持聚合操作。你需要把它变成:

NSPredicate *p = [NSPredicate predicateWithFormat:@"%K >= %@ AND %K <= %@", keyPath, lowerBound, keyPath, upperBound];

here ya go...

BETWEEN operations are aggregate operations, and aggregate operations are not supported by Core Data. You'll need to turn this into:

NSPredicate *p = [NSPredicate predicateWithFormat:@"%K >= %@ AND %K <= %@", keyPath, lowerBound, keyPath, upperBound];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文