Распределение, пока наблюдатели значения ключа еще зарегистрированы (обратный геокодер) - PullRequest
17 голосов
/ 22 февраля 2011

Когда мое представление исчезает, я получаю следующее сообщение:

An instance 0x1c11e0 of class MKAnnotationView was deallocated while key value observers were still registered with it. Observation info was 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:

(Контекст: 0x0, Свойство: 0x1e98d0>)

Код, который определяет и запускает обратное геокодирование:

geo=[[MKReverseGeocoder alloc] initWithCoordinate:droppedAt];
        geo.delegate=self;
        [geo start];

Я пытался установить для geo.delegate значение nil прямо перед тем, как я отклонил представление.Это было бы слишком просто.Я также пытался:

for (id <MKAnnotation> annotation in mvMap.annotations) {
    [[mvMap viewForAnnotation:annotation] removeObserver:self forKeyPath:@"selected"];
}

, который выдает ошибку, которая говорит:

* Завершение приложения из-за необработанного исключения «NSRangeException», причина: «Невозможно удалитьНаблюдатель для ключевого пути "выбран" из-за того, что он не зарегистрирован в качестве наблюдателя.

Мой вид кода аннотации такой:

-(MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
    MKAnnotationView *aView;

    aView=(MKAnnotationView *) [mapView dequeueReusableAnnotationViewWithIdentifier:annotation.title];
    if (aView==nil) 
        aView=[[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:annotation.title] autorelease];
    else
        aView.annotation=annotation;
    [aView setImage:[UIImage imageNamed:selIcon]];
    aView.canShowCallout=TRUE;
    aView.draggable=YES;
    return aView;
}

Я вроде нажимаю кнопки и переключаю переключателиздесь, пока крутится. Есть идеи, что я могу здесь сделать?

Ответы [ 2 ]

13 голосов
/ 30 марта 2011

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

Таким образом, ваш dealloc должен иметь (набранные в веб-браузере, возможно, вам придется настроить):

- (void) dealloc
{
     [[NSNotificationCenter defaultCenter] removeObserver: self];
     for (id <MKAnnotation> annotation in mvMap.annotations)
     {
          // remove all observers, delegates and other outward pointers.
          [[mvMap viewForAnnotation:annotation] removeObserver: self forKeyPath: path];
     }

     gel.delegate = nil;
     // etc., your other stuff
     [super dealloc];  // Only in non-ARC legacy code.  Modern stuff skips this.
}

Пройдите настройку (скорее всего, в viewDidLoad) и убедитесь, что вы отменили все, что вы там делали. В частности, все, что вызывает обратный вызов.

2 голосов
/ 28 октября 2011

У меня такие же проблемы с перетаскиваемыми булавками.Я обнаружил, что следующий код решает их:

(void)mapView:(MKMapView *)theMapView annotationView:(MKAnnotationView *)annotationView didChangeDragState:(MKAnnotationViewDragState)newState fromOldState:(MKAnnotationViewDragState)oldState {

if (newState == MKAnnotationViewDragStateStarting) {

    // some my code

} else if (newState == MKAnnotationViewDragStateCanceling) {

    [annotationView removeObserver:theMapView forKeyPath:@"dragState"];

} else if (newState == MKAnnotationViewDragStateEnding) {

    [annotationView removeObserver:theMapView forKeyPath:@"dragState"];
}
}
...