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 开发者_StackOverflowa 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?
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];
}
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.
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;
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.
The following code is likely to asolve your problem:
-(void) viewWillDisappear:(BOOL)animated
{
self.mapView.delegate = nil;
mapView=Nil;
NSLog(@"viewWillDisappear");
}
精彩评论