Cocoa 为什么';这难道不是一项预期的工作吗?

Cocoa 为什么';这难道不是一项预期的工作吗?,cocoa,performance,comparison,predicate,nspredicate,Cocoa,Performance,Comparison,Predicate,Nspredicate,我有一个名为arrAnnotations的MKAnnotation对象数组。我想挑选一个与存储在名为“newLocation”的CLLocation对象中的注释具有相同坐标的注释 我正在尝试使用一个NSPredicate,但它不起作用 NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(SELF.coordinate == %f)", newLocation.coordinate]; NSArray* filteredArr

我有一个名为
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];

最后两个导致应用程序崩溃,第三个导致应用程序出现
NSInvalidArgumentException
[nsconcertevalue compare:][/code>和第四个,因为
latitude
不符合键值编码(我假设这是因为坐标只是
c-struct
而不是
NSObject
?)

如何使用
NSPredicate
? 谁能给我一个文档的链接,这个文档展示了谓词是如何工作的? 我不明白他们到底在做什么,尽管我已经阅读并理解了苹果的大部分内容。
用谓词搜索一个巨大的数组是否比用for…in构造循环更有效?如果是/否,原因是什么?

MKAnnotation协议的坐标属性是一个
struct
,因此根据

您可以使用
NSPredicate
predicateWithBlock:
来完成您试图完成的任务,但是您必须小心使用
CLLocationCoordinate2D
以及如何比较它是否相等

CLLocationCoordinate2D
纬度
经度
属性是数据类型,根据定义是一个
双精度

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

考虑到所有这些,我相信对谓词使用下面的代码可能会解决您的问题

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

}];
NSPredicate*谓词=[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject,NSDictionary*绑定){
id注释=evaluatedObject;
如果(fabsf([注释坐标].纬度-[新位置坐标].纬度)<0.000001
&&fabsf([注释坐标].经度-[新位置坐标].经度)<0.000001){
返回YES;
}否则{
返回否;
}
}];

MKAnnotation协议的坐标属性是一个
结构
,因此根据

您可以使用
NSPredicate
predicateWithBlock:
来完成您试图完成的任务,但是您必须小心使用
CLLocationCoordinate2D
以及如何比较它是否相等

CLLocationCoordinate2D
纬度
经度
属性是数据类型,根据定义是一个
双精度

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

考虑到所有这些,我相信对谓词使用下面的代码可能会解决您的问题

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

}];
NSPredicate*谓词=[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject,NSDictionary*绑定){
id注释=evaluatedObject;
如果(fabsf([注释坐标].纬度-[新位置坐标].纬度)<0.000001
&&fabsf([注释坐标].经度-[新位置坐标].经度)<0.000001){
返回YES;
}否则{
返回否;
}
}];

不能仅将结构解释为
double
。您可以通过
NSLog(@“%f”,一个坐标)获得一些信息
但这是未定义的行为,可能会导致崩溃等。由于
NSPredicate
不适用于C-structs,您可以暂时使用显式测试,除非有CoreLocation经验的人知道更好的替代方法。您不能仅将struct解释为
double
。您可能会通过
NSLog(@“%f”,一个坐标)
得到一些信息,但这是未定义的行为,可能会导致崩溃等。由于
NSPredicate
不适用于C-structs,您可以暂时使用显式测试,除非有CoreLocation经验的人知道更好的替代方法。
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;
    }

}];