在放大时使用MKMapView在setUserTrackingMode上崩溃

我有MKUserTrackingModeFollowWithHeading MKMapView。 但是有些东西把userTrackingMode改为MKUserTrackingModeFollow或None,所以我实现了,

- (void)mapView:(MKMapView *)mapView didChangeUserTrackingMode:(MKUserTrackingMode)mode animated:(BOOL)animated { if ([CLLocationManager locationServicesEnabled]) { if ([CLLocationManager headingAvailable]) { [self.myMapView setUserTrackingMode:MKUserTrackingModeFollowWithHeading animated:NO]; }else{ [self.myMapView setUserTrackingMode:MKUserTrackingModeFollow animated:NO]; } }else{ [self.myMapView setUserTrackingMode:MKUserTrackingModeNone animated:NO]; } } 

一切都很好,但每次我放大地图到最详细的水平,应用程序导致EXC_BAD_ACCESS行setUserTrackingMode:MKUserTrackingModeFollowWithHeading上面显示。

我应该怎么做才能避免崩溃? 如果可能,我不想使用MKUserTrackingBarButtonItem。

下面是mapViewController的其他部分。

 - (void)dealloc { self.myMapView.delegate = nil; } - (void)viewWillDisappear:(BOOL)animated { if ([CLLocationManager locationServicesEnabled]) { self.myMapView.showsUserLocation = NO; [_locManager stopUpdatingLocation]; if ([CLLocationManager headingAvailable]) { [_locManager stopUpdatingHeading]; } } [super viewWillDisappear:animated]; } - (void)viewDidAppear:(BOOL)animated { if ([CLLocationManager locationServicesEnabled]) { self.myMapView.showsUserLocation = YES; [_locManager startUpdatingLocation]; if ([CLLocationManager headingAvailable]) { [self.myMapView setUserTrackingMode:MKUserTrackingModeFollowWithHeading animated:NO]; [_locManager startUpdatingHeading]; }else{ [self.myMapView setUserTrackingMode:MKUserTrackingModeFollow animated:NO]; } }else{ [self.myMapView setUserTrackingMode:MKUserTrackingModeNone animated:NO]; } } - (void)viewWillAppear:(BOOL)animated { [super viewDidAppear:animated]; self.myMapView.delegate = self; [self.myMapView setFrame:self.view.frame]; self.locManager = [CLLocationManager new]; [self.locManager setDelegate:self]; [self.locManager setDistanceFilter:kCLDistanceFilterNone]; [self.locManager setDesiredAccuracy:kCLLocationAccuracyBest]; [self.locManager setHeadingFilter:3]; [self.locManager setHeadingOrientation:CLDeviceOrientationPortrait]; } 

任何types的build议表示赞赏。 先谢谢你。

我将最小的示例代码上传到github 。

我可能会build议尝试推迟跟踪模式的设置,例如:

 - (void)mapView:(MKMapView *)mapView didChangeUserTrackingMode:(MKUserTrackingMode)mode animated:(BOOL)animated { dispatch_async(dispatch_get_main_queue(),^{ if ([CLLocationManager locationServicesEnabled]) { if ([CLLocationManager headingAvailable]) { [self.myMapView setUserTrackingMode:MKUserTrackingModeFollowWithHeading animated:NO]; }else{ [self.myMapView setUserTrackingMode:MKUserTrackingModeFollow animated:NO]; } }else{ [self.myMapView setUserTrackingMode:MKUserTrackingModeNone animated:NO]; } }); } 

我也可能build议检查以确保mode不是你想要的,消除了冗余的setUserTrackingMode

 - (void)mapView:(MKMapView *)mapView didChangeUserTrackingMode:(MKUserTrackingMode)mode animated:(BOOL)animated { MKUserTrackingMode newMode = MKUserTrackingModeNone; if ([CLLocationManager locationServicesEnabled]) { if ([CLLocationManager headingAvailable]) { newMode = MKUserTrackingModeFollowWithHeading; }else{ newMode = MKUserTrackingModeFollow; } } if (mode != newMode) { dispatch_async(dispatch_get_main_queue(), ^{ [self.myMapView setUserTrackingMode:newMode animated:YES]; }); } } 

你也可以把它和scrollEnabled结合起来(这样可以防止用户偶然地启动跟踪模式的改变)。

Swift 3

 func mapView(_ mapView: MKMapView, didChange mode: MKUserTrackingMode, animated: Bool) { var newMode: MKUserTrackingMode = .none if ( CLLocationManager.locationServicesEnabled() ) { if ( CLLocationManager.headingAvailable() ) { newMode = .followWithHeading } else { newMode = .follow } } if (mode != newMode) { DispatchQueue.main.async { mapView.setUserTrackingMode(newMode, animated: true) } } }