MKMapView crashes app when view controller popped
Asked Answered
D

5

6

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?

Disburse answered 1/9, 2011 at 10:53 Comment(2)
This is interesting. Our app is being crippled by baffling crashes that occur when an MKMapView calls the delegate to get a view for an annotation. The problem is that there IS no MKMapView in existence at that point; or there shouldn't be. The controller containing it has long since been popped. Wonder if it's the same problem.Noumenon
Looks like the same problem as this: #2188598Noumenon
D
14

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];
}
Disburse answered 2/9, 2011 at 1:26 Comment(2)
It wasn't possible to do this in viewWillDisappear?Noumenon
@Oscar: I was just about to take Jiho's answer then saw your your suggestion. Should work if done in viewWillDisapear.Math
N
8

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.

Noumenon answered 20/11, 2011 at 21:18 Comment(1)
This applies to any object which may live longer than its delegate.Emergence
S
0

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;

Sweyn answered 21/11, 2015 at 9:45 Comment(0)
F
0

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.

Fuselage answered 25/4, 2019 at 10:19 Comment(0)
K
-1

The following code is likely to asolve your problem:

-(void) viewWillDisappear:(BOOL)animated
{
    self.mapView.delegate = nil;
    mapView=Nil;
    NSLog(@"viewWillDisappear");

}
Krick answered 18/4, 2013 at 11:37 Comment(1)
You forgot to call super method of viewWillDisappear:animatedBarrettbarrette

© 2022 - 2024 — McMap. All rights reserved.