我有一个名为 arrAnnotations
的 MKAnnotation
对象数组。我想挑选出与存储在名为“newLocation”的 CLLocation 对象中具有相同坐标的注释之一。
我正在尝试使用 NSPredicate
,但它不起作用。
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(SELF.coordinate == %f)", newLocation.coordinate];
NSArray* filteredArray = [arrAnnotations filteredArrayUsingPredicate:predicate];
[self.mapView selectAnnotation:[filteredArray objectAtIndex:0] animated:YES];
filteredArray 始终包含零个对象。
我也尝试过以下方法,但都不起作用
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(coordinate == %f)", newLocation.coordinate];
和
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(coordinate > 0)"];
和
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(coordinate.latitude == %f)", newLocation.coordinate.latitude];
最后两个使应用程序崩溃,第三个是 [NSConcreteValue Compare:]
出现 NSInvalidArgumentException
,第四个是因为 latitude
是不符合键值编码(我认为这是因为坐标只是一个 c-struct
而不是 NSObject
?)。
如何使用 NSPredicate
实现此功能?
谁能给我一个文档的链接,该文档展示了谓词在幕后如何工作?
我不明白他们实际上做了什么,尽管我已经阅读并理解了 Apple Predicate Programming Guide 的大部分内容。 。
使用谓词搜索一个巨大的数组是否比仅使用 for...in 结构循环遍历它更有效?如果是/否,为什么?
最佳答案
MKAnnotation 协议(protocol)的坐标属性是 CLLocationCoordinate2D struct
,因此根据 Predicate Format String Syntax 在 NSPredicate
格式语法中不允许使用它。
您可以使用 NSPredicate
predicateWithBlock:
来完成您想要做的事情,但是您必须小心 CLLocationCooperative2D
以及如何比较一下是否相等。
CLLocationCooperative2D
的 latitude
和 longitude
属性为 CLLocationDegrees数据类型,根据定义是 double
。
通过快速搜索,您可以找到在比较浮点值是否相等时会遇到的问题的几个示例。可以找到一些很好的例子 here , here和 here .
鉴于所有这些,我相信使用下面的代码作为您的谓词可能会解决您的问题。
NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
id<MKAnnotation> annotation = evaluatedObject;
if (fabsf([annotation coordinate].latitude - [newLocation coordinate].latitude) < 0.000001
&& fabsf([annotation coordinate].longitude - [newLocation coordinate].longitude) < 0.000001) {
return YES;
} else {
return NO;
}
}];
关于cocoa - 为什么这个 NSPredicate 不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3310277/