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

Освобождение, в то время как наблюдатели с ключевыми значениями все еще зарегистрированы (обратный геокодер)

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

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 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;
}

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

4b9b3361

Ответ 1

Здесь может быть несколько проблем. Для каждого делегата, который вы создали, вы должны очистить его в 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

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

(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"];
}
}