Why am I crashing after MKMapView is freed if I'm no longer using it?
Asked Answered
F

4

24

I have a MKMapView. Sometimes after my view controller is dismissed, I'll get a EXC_BAD_ACCESS.

I turned on NSSZombies and it looks like the MKMapView's delegate — my view controller! — is being called, despite both the MKMapView and UIViewController subclass being freed. I've checked, and my memory management is correct.

What's going on?

Far answered 2/2, 2010 at 22:10 Comment(0)
F
44

This is because of the way MKMapView works. There's an operation pending, so MapKit is retaining the MKMapView and it hasn't actually been deallocated yet. That isn't itself a problem. The problem is that it's still sending messages to your delegate.

The workaround is simple: As part of your view controller's cleanup set the map view's delegate to nil, which will prevent MKMapView from sending messages to it.

This is documented in MKMapViewDelegate Protocol Reference:

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.

Edit: Give Oscar an upvote as well, just below, who provided the documentation quote here.

Given ARC, I suggest this means you should set your map view's delegate to nil in your view controller's dealloc.

Far answered 2/2, 2010 at 22:18 Comment(1)
Thanks. My question is whether we were supposed to know this somehow. If this is expected of users of MapView, then why don't we have to clear the delegate pointer of ALL controls that take a delegate?Fipple
F
18

OK, this is the confirmation of the 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.

Fipple answered 20/11, 2011 at 21:20 Comment(1)
I wasn't aware that Apple had documented this behaviour anywhere. Thanks; I've added the link to my answer (which also covers the why of it).Far
C
2

Setting the map view's delegate to nil didn't work for me. However, setting showsUserLocation=NO on the delegate worked by making sure no location updates are received.

Coequal answered 2/9, 2011 at 16:57 Comment(1)
Did you have the map view connected? I'm guessing it was nil.Far
P
0

The problem, in my case, was that first time I launched app I don't press "allow" when prompting for location authorization (accidentally!!).

Uninstalling app and re-installing it, when prompt appear I allow the authorizations and no more crash!

Phototube answered 21/5, 2015 at 15:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.