Подтвердить что ты не робот

Почему я сбой после освобождения MKMapView, если я больше не использую его?

У меня есть MKMapView. Иногда, когда мой диспетчер просмотров отклоняется, я получаю EXC_BAD_ACCESS.

Я включил NSSZombies, и он выглядит как делегат MKMapView - мой контроллер просмотра! - вызывается, несмотря на освобождение подкласса MKMapView и UIViewController. Я проверил, и мое управление памятью правильно.

Что происходит?

4b9b3361

Ответ 1

Это связано с тем, как работает MKMapView. Там ожидается операция, поэтому MapKit сохраняет MKMapView, и он пока еще не освобожден. Это само по себе не проблема. Проблема в том, что он по-прежнему отправляет сообщения вашему делегату.

Обходной путь прост: в качестве части вашей очистки контроллера View установите делегат отображения карты на nil, что предотвратит отправку ему сообщений MKMapView.

Это описано в Ссылка на протокол MKMapViewDelegate:

Перед выпуском объекта MKMapView, для которого вы установили делегат, не забудьте установить для свойства делегирования объектов значение nil. Одно место, которое вы можете сделать это, - это метод dealloc, где вы располагаете видом карты.

Изменить: Дайте Оскару также верхнюю часть, чуть ниже, которая указала здесь цитату с документацией.

Учитывая ARC, я предлагаю, чтобы это означало, что вы должны назначить делегат отображения карты nil в вашем контроллере просмотра dealloc.

Ответ 2

ОК, это подтверждение ответа. Это из документа Apple, но он отсутствует в MKMapView. Он найден только в документации по протоколу делегата:

Перед выпуском объекта MKMapView, для которого вы установили делегат, не забудьте установить для свойства делегирования объектов значение nil. Один место, которое вы можете сделать, это метод dealloc, в котором вы распоряжаетесь вид карты.

ПРИМЕЧАНИЕ. Это также относится к UIWebView.

Я установил указатель делегата MapView на нуль в методе делегата dealloc, и наши сбои, похоже, были устранены.

Ответ 3

Настройка делегата отображения карты на nil не помогла мне. Тем не менее, установка showsUserLocation=NO в делегате работала, убедившись, что никаких обновлений местоположения не получено.

Ответ 4

Проблема в моем случае заключалась в том, что в первый раз, когда я запустил приложение, я не нажимаю "разрешить" при запросе авторизации местоположения (случайно!).

Удаление приложения и его повторная установка, когда появится приглашение, я разрешаю авторизацию и больше не сбой!