crash en setUserTrackingMode con MKMapView cuando se amplía

Tengo MKMapView con MKUserTrackingModeFollowWithHeading. Pero algo cambia el userTrackingMode a MKUserTrackingModeFollow o None, así que implementé,

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

Todo está bien, pero cada vez que acerco el map al nivel más detallado, la aplicación hace EXC_BAD_ACCESS en la línea setUserTrackingMode: MKUserTrackingModeFollowWithHeading se muestra arriba.

¿Qué debo hacer para evitar chocar? No quiero usar MKUserTrackingBarButtonItem si es posible.

La otra parte del mapViewController está debajo.

 - (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 setDesinetworkingAccuracy:kCLLocationAccuracyBest]; [self.locManager setHeadingFilter:3]; [self.locManager setHeadingOrientation:CLDeviceOrientationPortrait]; } 

Cualquier tipo de asesoramiento apreciado. Gracias de antemano.

Subo el mínimo código de muestra a github .

Tal vez sugiera tratar de aplazar la configuration del modo de seguimiento, por ejemplo:

 - (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]; } }); } 

También podría sugerir que se compruebe para asegurarse de que el mode no es lo que desea, eliminando un setUserTrackingMode networkingundante:

 - (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]; }); } } 

También podría combinar eso con scrollEnabled (que debería evitar que el usuario incidentalmente inicie un cambio en el modo de seguimiento).

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