Perché sto andando in crash dopo che MKMapView è stato liberato se non lo uso più?

Ho un MKMapView . A volte, dopo che il mio controller di visualizzazione è stato rimosso, EXC_BAD_ACCESS un EXC_BAD_ACCESS .

Ho acceso NSSZombies e sembra il delegato di MKMapView – my view controller! – viene chiamato, nonostante sia stata liberata la sottoclass di MKMapView e UIViewController . Ho controllato e la mia gestione della memoria è corretta.

Cosa sta succedendo?

Questo è dovuto al modo in MKMapView funziona MKMapView . C’è un’operazione in sospeso, quindi MapKit mantiene il MKMapView e non è stato ancora deallocato. Questo non è di per sé un problema. Il problema è che sta ancora inviando messaggi al tuo delegato.

La soluzione è semplice: come parte della pulizia del controller della vista, imposta il delegato della vista mappa su nil , il che impedirà a MKMapView di inviare messaggi ad esso.

Questo è documentato in MKMapViewDelegate Protocol Reference :

Prima di rilasciare un object MKMapView per il quale è stato impostato un delegato, ricordare di impostare la proprietà delegato dell’object su zero. Un posto che puoi fare è nel metodo dealloc in cui disponi della vista mappa.

Modifica: Regala anche un commento su Oscar, appena sotto, che ha fornito la citazione della documentazione qui.

Dato ARC, ti suggerisco di impostare il delegato della visualizzazione della mappa su nil nel dealloc del tuo controller di dealloc .

OK, questa è la conferma della risposta. Viene dal documento Apple, ma manca da MKMapView. Si trova solo sotto la documentazione per il suo protocollo delegato:

Prima di rilasciare un object MKMapView per il quale è stato impostato un delegato, ricordare di impostare la proprietà delegato dell’object su zero. Un posto che puoi fare è nel metodo dealloc in cui disponi della vista mappa.

NOTA: questo vale anche per UIWebView.

Ho impostato il puntatore del delegato di MapView su zero nel metodo dealloc del delegato, e sembra che i nostri arresti anomali siano stati eliminati.

L’impostazione del delegato della vista mappa su nil non ha funzionato per me. Tuttavia, l’impostazione showsUserLocation=NO sul delegato ha funzionato assicurandosi che non vengano ricevuti aggiornamenti di posizione.

Il problema, nel mio caso, è che quando ho lanciato l’app per la prima volta non faccio clic su “consenti” quando chiedo l’authorization della posizione (accidentalmente !!).

Disinstallando l’app e reinstallandola, quando viene visualizzata la richiesta, permetto le autorizzazioni e non più crash!