1

我有一个MKAnnotation名为arrAnnotations. 我想挑选一个与存储在CLLocation名为“newLocation”的对象中的注释具有相同坐标的注释。

我正在尝试使用 a NSPredicate,但它不起作用。

NSPredicate *predicate = [NSPredicate  predicateWithFormat:@"(SELF.coordinate == %f)", newLocation.coordinate];
NSArray* filteredArray = [arrAnnotations filteredArrayUsingPredicate:predicate];
[self.mapView selectAnnotation:[filteredArray objectAtIndex:0] animated:YES];

filtersArray 始终包含零个对象。

我也尝试了以下方法,它们也不起作用

NSPredicate *predicate = [NSPredicate  predicateWithFormat:@"(coordinate == %f)", newLocation.coordinate];

NSPredicate *predicate = [NSPredicate  predicateWithFormat:@"(coordinate > 0)"];

NSPredicate *predicate = [NSPredicate  predicateWithFormat:@"(coordinate.latitude == %f)", newLocation.coordinate.latitude];

最后两个使应用程序崩溃,第三个带有NSInvalidArgumentExceptionfor[NSConcreteValue compare:]和第四个,因为latitude不符合键值编码(我认为这是因为坐标只是 ac-struct而不是NSObject?)。

我怎样才能使这个工作NSPredicate?谁能给我一个文档链接,该文档显示谓词如何在幕后工作?尽管我已经阅读并理解了 Apple 的Predicate Programming Guide的大部分内容,但我不明白他们实际上在做什么。使用谓词搜索一个巨大的数组是否比使用 for...in 构造循环遍历它更有效?如果是/否,为什么?

4

1 回答 1

6

MKAnnotation 协议的坐标属性是CLLocationCoordinate2D ,因此根据Predicate Format String Syntaxstruct在格式语法中是不允许的NSPredicate

您可以NSPredicate predicateWithBlock:改为使用来完成您正在尝试做的事情,但您必须小心CLLocationCoordinate2D以及如何比较它是否相等。

CLLocationCoordinate2Dlatitudelongitude属性是CLLocationDegrees数据类型,这是一个double定义。

通过快速搜索,您可以找到几个在比较浮点值是否相等时会遇到的问题示例。可以在此处此处此处找到一些很好的示例。

鉴于这一切,我相信使用下面的代码作为谓词可能会解决您的问题。

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;
    }

}];
于 2011-06-30T00:52:34.290 回答