MKMapView аварийно завершает работу приложения, когда отображается контроллер

У меня есть контроллер представления с MKMapView, который вызывает

[self.mapView setRegion:region animated:YES]; 

который перемещает карту от А до Б.

Контроллер представления, который содержит MKMapView, устанавливается в качестве делегата и

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated

У меня есть некоторый код, который вызовет другой setRegion: animated: к MKMapView, так что карта автоматически увеличит новую позицию.

Все работает нормально, если я popViewControllerAnimated: контроллер представления ПОСЛЕ анимации MKMapView выполняет панорамирование и масштабирование.

Однако, когда я пытаюсь использовать popViewControllerAnimated: текущий контроллер представления, пока MKMapView выполняет анимацию, приложение вылетает с "сообщением, отправленным в освобожденный экземпляр".

Судя по отладчику, я думаю, что MKMapView пытается вызвать метод из удаленного и освобожденного делегата.

Так я попробовал

[self.mapView setDelegate:nil];
self.mapView = nil;

в viewDidUnload не повезло. Приложение по-прежнему падает последовательно.

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

Почему это происходит? Есть ли другие "чистые" варианты?

4 ответа

Решение

Друг помог мне получить это.

Я реализовал свой собственный метод для вызова контроллера представления вместо использования кнопки возврата контроллера навигации по умолчанию. Мне просто нужно было добавить [self.mapView setDelegate:nil]; прежде чем я выскочил вид контроллера.

- (void)goBack
{
    [self.mapView setDelegate:nil];
    [self.navigationController popViewControllerAnimated:YES];
}

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

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

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

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

Я сделал кластеризацию и отмечал аннотацию, выбранную так mapView.selectAnnotation(annotation, animated: true),

пока выскочил, deinit метод, используемый для сбоя.

Поэтому при нажатии кнопки "назад" я просто добавляю эту строку mapView.deselectAnnotation(selectedAnnotation, animated: false) и это решило крах.

Моя проблема не была решена путем установки делегата MKMapView на ноль в моем представлении контроллера

[self.mapView setDelegate:nil];

Я должен был сделать сильную ссылку на мой UIViewController, содержащий MKMapView в моем RootViewController.

__strong <# UIViewController #> * vcNewLocation;

Следующий код может решить вашу проблему:

-(void) viewWillDisappear:(BOOL)animated
{
    self.mapView.delegate = nil;
    mapView=Nil;
    NSLog(@"viewWillDisappear");

}
Другие вопросы по тегам