2010-07-22 63 views
1

我有一個MKAnnotation對象數組,稱爲arrAnnotations。我想用與存儲在名爲「newLocation」的CLLocation對象中的座標相同的座標挑選其中一個註釋。我想使用NSPredicate,但它不起作用。爲什麼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]; 

最後兩個崩潰的應用程序,第三個用NSInvalidArgumentException[NSConcreteValue compare:]和第四個,因爲latitude是而不是鍵值編碼兼容(我認爲這是因爲座標只是一個c-struct而不是一個NSObject?)。

如何使用NSPredicate進行此項工作? 任何人都可以給我一個鏈接到一個文件,顯示Predicates如何在引擎蓋下工作? 雖然我已經閱讀並理解了蘋果的大部分Predicate Programming Guide,但我不明白他們實際上做了什麼。 正在搜索一個龐大的數組,其謂詞比循環遍歷for ... in構造更有效嗎?如果是/否,爲什麼?

+0

你不能只將結構解釋爲'double'。你可能會用'NSLog(@「%f」,aCoordinate)得到一些東西,但這是未定義的行爲,並可能導致崩潰等。由於'NSPredicate'不能用於C-structs,因此你可以使用顯式測試除非有CoreLocation經驗的人知道更好的選擇。 – 2010-07-22 15:27:53

回答

6

MKAnnotation協議的座標屬性是CLLocationCoordinate2Dstruct,因此它不是在NSPredicate格式語法允許根據Predicate Format String Syntax

你可以使用NSPredicatepredicateWithBlock:,而不是完成你正在嘗試做的,但你必須要小心與CLLocationCoordinate2D以及如何比較它是否相等。

CLLocationCoordinate2Dlatitudelongitude屬性是CLLocationDegrees數據類型,這是一個由double定義。

通過快速搜索,您可以找到幾個比較浮點值相等時所面臨問題的示例。一些很好的例子可以參見here,herehere

鑑於這一切,我相信使用代碼爲您的謂詞可能會解決您的問題。

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

}];