EDIT: изменено название. Я не знал этого в то время, но это дубликат Почему я сбой после освобождения MKMapView, если я больше не использую его?
Этот вопрос похож на Почему объект не отменяется при использовании ARC + NSZombieEnabled, но достаточно разный, что я думал, что стоит выбросить его на случай, если кто-нибудь поймет и может объяснить мне, что происходит. Другой вопрос может быть ошибкой XCode, поэтому я предполагаю, что это может быть похоже.
Сценарий:
-
RootViewControllerимеетtableView, отображающий кучу элементов - Выбор ячейки представляет модальный
detailViewController, содержащий другойtableView - Одна из ячеек таблицы в
detailViewControllerсодержитMKMapView, показывающую расположение элемента -
mapView.delegate = detailViewController - Отключить модальный
detailViewController
Вскоре после этого приложение сбой b/c MKMapView отправляет mapView:viewForAnnotation: в dealloc'ed detailViewController. Этот сбой, воспроизведенный на пользовательском устройстве с раскладкой ad-hoc, поэтому проблема не имеет ничего общего с NSZombieEnabled.
Мне удалось решить проблему, добавив:
_mapView.delegate = nil;
к dealloc методу tableViewCell, содержащему mapView.
ВОПРОС: почему необходимо, чтобы делегат был отключен, когда ячейка отменена? Похоже, что mapView должен быть отменен ARC, когда ячейка освобождена, оставив это ненужным. Это хорошая практика для ноль делегатов, но я не думал, что это потребуется в этом случае.
EDIT: все подпункты как detailViewController, так и UITableViewCells объявлены как (nonatomic, strong) свойства ala:
@property (nonatomic, strong) MKMapView * mapView;
РЕДАКТИРОВАТЬ 2: Думаю, мне нужно лучше читать документы. @fluchtpunkt верен. Здесь соответствующая информация из документации MKMapView:
Перед выпуском объекта MKMapView, для которого вы установили делегат, не забудьте установить для свойства делегирования объектов значение nil. Один место, которое вы можете сделать, это метод dealloc, в котором вы распоряжаетесь вид карты.