Получение исключения при использовании КВО - PullRequest
0 голосов
/ 01 ноября 2010

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

[annView  addObserver:self
       forKeyPath:@"selected" 
       options:NSKeyValueObservingOptionNew
       context:@"ANSELECTED"];

Он работает, как ожидалось, но некоторое время получает исключение 'EXC_BAD_ACCESS'Мой журнал выглядит следующим образом, и он показывает мне утечку памяти.Нужно ли освобождать сервер?Если я ?тогда где я должен выпустить это?

An instance 0x1b21f0 of class MKAnnotationView is being deallocated
while key value observers are still registered with it. Observation
info is being leaked, and may even become mistakenly attached to
some other object. Set a breakpoint on NSKVODeallocateBreak to stop
here in the debugger. Here's the current observation info:

<NSKeyValueObservationInfo 0x11e5f0> (
<NSKeyValueObservance 0x1b1da0: Observer: 0x120f70, Key path: selected, Options: <New: YES, Old: NO, Prior: NO> Context: 0x2b588, Property: 0x1acaa0>

Ответы [ 3 ]

3 голосов
/ 01 ноября 2010

Это работает как исключение, но некоторое время это получает исключение 'EXC_BAD_ACCESS'.Мой журнал выглядит следующим образом, и он показывает мне утечку памяти.…

An instance 0x1b21f0 of class MKAnnotationView is being deallocated while key value observers are still registered with it.

Это противоположность утечки.Это это освобождается;утечка - это когда объект никогда не будет освобожден.

Проблема заключается в том, что он освобождается, пока что-то еще все еще наблюдает за ним.Все, что все еще наблюдает за этим объектом, может также послать ему другие сообщения позже;когда это произойдет, эти сообщения будут отправлены на мертвый объект (вызывающий сбой, который вы видели, который произошел после этого сообщения) или на другой объект.

Если объект, наблюдающий MKAnnotationView, владеет им и освобождаетэто, это должно удалить себя как наблюдателя прежде, чем выпустить это.Если он не владеет им, он, вероятно, должен.

1 голос
/ 01 ноября 2010

Вы должны прекратить наблюдать за аннотацией, прежде чем ее отпустить:

[annView removeObserver:self forKeyPath:@"selected"];
0 голосов
/ 23 сентября 2014

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

Вы должны создать ивар NSMutableArray в своем классе контроллера представления, чтобы сохранить ссылку на ваше представление аннотаций:

MyMapViewController <MKMapViewDelegate> {
NSMutableArray *annot;

}

Инициализируйте его в вашем viewDidLoad и в вашем - (MKAnnotationView *) mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>) annotation Вы должны добавить MKAnnotationView к самому изменяемому массиву непосредственно перед кодом annView addObserver:

 if(nil == annView) {
    annView = [[MyAnnotationView alloc] initWithAnnotation:myAnnotation reuseIdentifier:identifier];
    [annot addObject:annView];
}


[annView addObserver:self
          forKeyPath:@"selected"
             options:NSKeyValueObservingOptionNew
             context:(__bridge void *)(GMAP_ANNOTATION_SELECTED)];

Затем в вашем методе viewDidDisappear вы можете выполнить итерацию массива и вручную удалить всех наблюдателей:

    //remove observers from annotation
for (MKAnnotationView *anView in annot){
    [anView removeObserver:self forKeyPath:@"selected"];
}

[annot removeAllObjects];

[super viewDidDisappear:animated];
...