我想计算用户和所有注释之间的距离。
我的注释来自已解析的 csv 文件。我的注释位于 Location
类中。除了距离计算之外,一切正常。
为了计算距离,我找到了这段代码:
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)newLocation
{
for (Location *annotation in self.mapView.annotations) {
CLLocationCoordinate2D coord = [annotation coordinate];
CLLocationCoordinate2D userCoordinate = [[[self.mapView userLocation] location] coordinate];
CLLocation *myLoc = [[CLLocation alloc] initWithLatitude:coord.latitude longitude:coord.longitude];
CLLocation *userLoc = [[CLLocation alloc] initWithLatitude:userCoordinate.latitude longitude:userCoordinate.longitude];
annotation.distance = [myLoc distanceFromLocation:userLoc];
NSLog(@"Distance is = %f", annotation.distance);
} // ! CRASH !
NSArray *sortedArray;
sortedArray = [self.mapView.annotations sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
NSNumber *first = [NSNumber numberWithDouble:[(Location*)a distance]];
NSNumber *second = [NSNumber numberWithDouble:[(Location*)b distance]];
return [first compare:second];
}];
但是我的应用程序在循环结束之前崩溃。我发现,通过断点,有一个奇怪的注释(MKUserLocation*
而不是 Location*
);在这个 MKUserLocation*
之后,应用程序崩溃了:
不正常(崩溃):
确定(没有崩溃):
为什么我的self.mapView.annotations
中有MKUserLocation
?如何忽略它?
日志:
2014-09-22 06:01:47.965 MyFirstGPS2[472:60b] -[MKUserLocation setDistance:]: unrecognized selector sent to instance 0x9db0bb0
2014-09-22 06:01:48.030 MyFirstGPS2[472:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[MKUserLocation setDistance:]: unrecognized selector sent to instance 0x9db0bb0'
*** First throw call stack:
(
0 CoreFoundation 0x01d971e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x01b168e5 objc_exception_throw + 44
2 CoreFoundation 0x01e34243 -[NSObject(NSObject) doesNotRecognizeSelector:] + 275
3 CoreFoundation 0x01d8750b ___forwarding___ + 1019
4 CoreFoundation 0x01d870ee _CF_forwarding_prep_0 + 14
5 MyFirstGPS2 0x00005043 -[HPViewController mapView:didUpdateUserLocation:] + 1203
6 MapKit 0x006825e6 -[MKMapView(MKHeadingAdditions) _stopTrackingHeading] + 469
7 MapKit 0x00666a92 -[MKMapView _setUserTrackingMode:animated:fromTrackingButton:] + 301
8 MapKit 0x00666960 -[MKMapView setUserTrackingMode:animated:] + 56
9 MapKit 0x00682176 -[MKMapView(MKHeadingAdditions) disableHeadingTracking:] + 65
10 MapKit 0x00669524 -[MKMapView _didChangeRegionMidstream:] + 672
11 MapKit 0x00671fbd -[MKMapView mapLayerDidChangeVisibleRegion:] + 66
12 VectorKit 0x0407a15e -[VKMapView mapDidChangeVisibleRegion:] + 78
13 VectorKit 0x040821fe -[VKMapCanvas cameraControllerDidChangeCameraState:] + 46
14 VectorKit 0x0409f1f7 -[VKMapCameraController updatePanWithTranslation:] + 231
15 VectorKit 0x0408268f -[VKMapCanvas updatePanWithTranslation:] + 63
16 VectorKit 0x0407aca9 -[VKMapView updatePanWithTranslation:] + 73
17 MapKit 0x0069e30b -[MKMapGestureController handlePan:] + 530
18 UIKit 0x00b724f4 _UIGestureRecognizerSendActions + 230
19 UIKit 0x00b71168 -[UIGestureRecognizer _updateGestureWithEvent:buttonEvent:] + 383
20 UIKit 0x00b72bdd -[UIGestureRecognizer _delayedUpdateGesture] + 60
21 UIKit 0x00b7613d ___UIGestureRecognizerUpdate_block_invoke + 57
22 UIKit 0x00b760be _UIGestureRecognizerRemoveObjectsFromArrayAndApplyBlocks + 317
23 UIKit 0x00b6c7ac _UIGestureRecognizerUpdate + 199
24 UIKit 0x00817a5a -[UIWindow _sendGesturesForEvent:] + 1291
25 UIKit 0x00818971 -[UIWindow sendEvent:] + 1021
26 UIKit 0x007ea5f2 -[UIApplication sendEvent:] + 242
27 UIKit 0x007d4353 _UIApplicationHandleEventQueue + 11455
28 CoreFoundation 0x01d2077f __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
29 CoreFoundation 0x01d2010b __CFRunLoopDoSources0 + 235
30 CoreFoundation 0x01d3d1ae __CFRunLoopRun + 910
31 CoreFoundation 0x01d3c9d3 CFRunLoopRunSpecific + 467
32 CoreFoundation 0x01d3c7eb CFRunLoopRunInMode + 123
33 GraphicsServices 0x03acf5ee GSEventRunModal + 192
34 GraphicsServices 0x03acf42b GSEventRun + 104
35 UIKit 0x007d6f9b UIApplicationMain + 1225
36 MyFirstGPS2 0x00013592 main + 130
37 libdyld.dylib 0x0258a701 start + 1
38 ??? 0x00000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
注意:我正在使用此页面中的代码来解析 csv 文件,我认为这不是问题:http://blog.smartfrog.fr/post/32123941502/tutorial-ios-mapkit
最佳答案
MKUserLocation
并不是一个“奇怪”的注释。
它是当您将 showsUserLocation
设置为 YES
时, map View 添加的用户位置(蓝点)注释的记录类。
map View 的 annotations
数组包含添加到 map 的所有注释 - 无论是由您还是由 map View 添加(另请注意,这些注释不会按任何特定顺序排列) )。
为了确保仅处理 Location
类型的注释,您可以在处理之前使用 isKindOfClass
方法检查注释对象的类。
如果注释不属于该类,则跳过它(继续
循环)。
对数组进行排序的代码也会遇到类似的问题,因为它将尝试访问 MKUserLocation
注释上的 distance
属性。
我建议不要尝试从 map View 的 annotations
数组创建排序数组,而是在 for 循环中创建一个仅包含 Location
注释的单独数组(在在设置距离
的同时),然后对该数组进行排序。
在 for 循环中使用 isKindOfClass
和排序更改的示例:
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)newLocation
{
if (newLocation == nil) {
//can happen if still waiting for user permission
return;
}
if (!CLLocationCoordinate2DIsValid(newLocation.coordinate)) {
//can happen if just resumed from some time in the background
return;
}
//Declare and set user location variables outside the for-loop
//since they won't be changing during the loop...
CLLocationCoordinate2D userCoordinate = [[[self.mapView userLocation] location] coordinate];
CLLocation *userLoc = [[CLLocation alloc] initWithLatitude:userCoordinate.latitude longitude:userCoordinate.longitude];
//declare array in which you will put your Location annotations for sorting later...
NSMutableArray *locAnnArray = [NSMutableArray array];
//Declare the loop variable as a generic id<MKAnnotation>
for (id<MKAnnotation> annotation in self.mapView.annotations) {
//Before processing the annotation, check it it's of type Location...
if (! [annotation isKindOfClass:[Location class]]) {
continue;
}
//Cast annotation to Location so we can see the distance property...
Location *locAnn = (Location *)annotation;
CLLocationCoordinate2D coord = [locAnn coordinate];
CLLocation *myLoc = [[CLLocation alloc] initWithLatitude:coord.latitude longitude:coord.longitude];
locAnn.distance = [myLoc distanceFromLocation:userLoc];
NSLog(@"Distance is = %f", locAnn.distance);
//Add Location annotation to local array for later sorting...
[locAnnArray addObject:locAnn];
}
//Sort our array of Location annotations...
[locAnnArray sortUsingComparator:^NSComparisonResult(id a, id b) {
NSNumber *first = [NSNumber numberWithDouble:[(Location*)a distance]];
NSNumber *second = [NSNumber numberWithDouble:[(Location*)b distance]];
return [first compare:second];
}];
//do something with the sorted array...
//...
}
关于ios - 为什么我的注释中包含 MKUserLocation?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25975951/