Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MKMapView crashes app when view controller popped

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?

like image 883
Jiho Kang Avatar asked Sep 01 '11 10:09

Jiho Kang


2 Answers

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];
}
like image 93
Jiho Kang Avatar answered Oct 14 '22 00:10

Jiho Kang


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.

like image 8
Oscar Avatar answered Oct 13 '22 23:10

Oscar