Chris Mays
Chris Mays

Reputation: 13

MKMapView Crash on Selection of Annotation and then Immediate deallocation of map view

I have a splitviewcontroller application where the master view controller is a UITableView and the detail view controller contains a MKMapView and a single annotation. When I make a selection in the UITableView the secondary view segues to a different map view with a single annotation.

When I select an annotation and then immediately afterwards (before the annotation popover appears) select a cell I receive an EXC_BAD_ACCESS crash. I used the Zombies tool to try and gather further information and I received this message.

An Objective-C message was sent to a deallocated 'MKPopoverBasedAnnotationCalloutController' object (zombie)

I believe the issue here is that the map view is still trying to display the annotations popover but the annotation has been deallocated.

So far I have tried:

•Setting MKMapView delegate nil on dealloc

Note: I am not using any custom popovers for the annotation. I also had a similar problem when calling [mapView selectAnnotation:mp animated:YES]; and then selecting another cell. I fixed this by just not calling it. This is obviously not an ideal solution.

Any suggestions on how to solve this? Or any insight on whether it is an issue with MapKit or an Issue with my application specifically?

Thanks in Advance, Chris

Upvotes: 1

Views: 490

Answers (1)

glued
glued

Reputation: 2629

I've been able to reproduce the issue consistently and it indeed looks like a bug with Apple's mapkit code. The only way i've been able to fix it was to create a singleton for MKMapView

-(MKMapView*)mapview{
    static MKMapView *_mapview = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _mapview = [[MKMapView alloc] initWithFrame:[UIScreen mainScreen].bounds];
        _mapview.showsPointsOfInterest = NO;
        _mapview.pitchEnabled = NO;
    });
    return _mapview;
}

An important note, when you remove the map don't clear the annotations yet, wait until you initialize it..

so not here...

-(void)viewDidDisappear:(BOOL)animated{
    [super viewDidDisappear:animated];
    [self.mapview removeFromSuperview];
     self.mapview.delegate = nil; //AND OR IN DEALLOC
}

but here ...

- (void)viewDidLoad{
    [super viewDidLoad];

    [self.view addSubview:self.mapview];
    self.mapview.delegate = self;

    [self.mapview removeAnnotations:[self.mapview annotations]];

    //RECREATE THOSE ANNOTATIONS
 }

Upvotes: 1

Related Questions