问题
I have a view controller with an MKMapView that calls
[self.mapView setRegion:region animated:YES];
which repositions the map from A to B.
The view controller which holds the MKMapView is set as the delegate and in
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
I have some code that will trigger another setRegion:animated: to the MKMapView so that the map will zoom in on the new position automatically.
Everything works fine if I popViewControllerAnimated: the view controller AFTER the MKMapView animation is done panning and zooming.
However, when I try to popViewControllerAnimated: the current view controller WHILE the MKMapView is running it's animation, the app crashes with "message sent to deallocated instance".
From the looks of the debugger, I think that MKMapView is trying to call a method from a popped and deallocated delegate.
So I tried
[self.mapView setDelegate:nil];
self.mapView = nil;
in viewDidUnload with no luck. The app still crashes consistently.
The only thing I could think of was to create a separate new delegate class and retain that class from the parent view controller so that the MKMapView would have a delegate to call even after the view controller that contains it is deallocated.
Why is this happening? Are there any other "clean" options?
回答1:
A friend helped me get this one.
I implemented my own method for popping the view controller instead of using the default navigation controller's back button. I just had to add [self.mapView setDelegate:nil]; before I popped the view controller.
- (void)goBack
{
[self.mapView setDelegate:nil];
[self.navigationController popViewControllerAnimated:YES];
}
回答2:
OK, this is the real answer. It's from the Apple doc, but it's missing from MKMapView. It's only found under the documentation for its delegate protocol:
"Before releasing an MKMapView object for which you have set a delegate, remember to set that object’s delegate property to nil. One place you can do this is in the dealloc method where you dispose of the map view."
NOTE: This also applies to UIWebView.
I set the MapView's delegate pointer to nil in the delegate's dealloc method, and our crashes seem to have been eliminated.
回答3:
My problem was not solved by setting delegate of MKMapView to nil in my view Controller
[self.mapView setDelegate:nil];
I had to make a __strong reference of my UIViewController containing MKMapView in my RootViewController.
__strong <#UIViewController#> *vcNewLocation;
回答4:
I had done Clustering and was marking the Annotation selected like so mapView.selectAnnotation(annotation, animated: true)
.
while popping, the deinit
method used to crash.
So on press of back button I just add this line mapView.deselectAnnotation(selectedAnnotation, animated: false)
and it solved the crash.
回答5:
The following code is likely to asolve your problem:
-(void) viewWillDisappear:(BOOL)animated
{
self.mapView.delegate = nil;
mapView=Nil;
NSLog(@"viewWillDisappear");
}
来源:https://stackoverflow.com/questions/7269303/mkmapview-crashes-app-when-view-controller-popped