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

iphone, mapkit, memory-management, mkmapview

Solution

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`.

Problem

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?

Original source