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

Когда следует удалять наблюдателей? Ошибка об удалении объектов перед удалением наблюдателей

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

Экземпляр 0x583870 класса TekkPoint освобождается, а наблюдатели ключевых значений по-прежнему регистрируются вместе с ним. Наблюдательная информация просачивается и может даже ошибочно привязываться к другому объекту. Установите точку останова на NSKVODeallocateBreak, чтобы остановить здесь в отладчике. Здесь текущая информация наблюдений:  (  Контекст: 0x0, Свойство: 0x536400 >  Контекст: 0x0, Свойство: 0x55aba0 > )

Есть ли способ удалить наблюдателей? Или, возможно, конкретное место, которое я должен удалить?

В соответствии с этим question я делаю все правильно, но зачем мне это сообщение об ошибке?

Вот моя процедура dealloc:

- (void)dealloc {
  // Remove all observers.
  for (NSString *path in [TekkPoint observedPaths]) {
    [self removeObserver:[option_ tChart]
          forKeyPath:path];

  }

  [description_ release];
  [weight_ release];
  [super dealloc];
}

Одно замечание, которое может показаться странным в моей реализации, заключается в том, что я добавляю и удаляю наблюдателей от наблюдателя, может ли это вызвать мою проблему?

4b9b3361

Ответ 1

Ах. Вы наблюдаете объект TekkPoint объекта SomethingElse, а объект SomethingElse - это тот, который добавляет и удаляет наблюдателей, правильно? (Что нормальный способ, все делается, я просто пытаюсь уточнить.)

Похоже, что ваш объект TekkPoint освобождается, а SomethingElse, который наблюдает его, все еще вокруг. Метод dealloc SomethingElse не вызывается, потому что он TekkPoint освобождается, а не SomethingElse.

Если вы планируете наблюдать объект, который может исчезнуть до исчезновения наблюдателя, вам нужно каким-то образом уведомить наблюдателей, что они должны удалить своих наблюдателей. Ваш TekkPoint может иметь свойство alive, которое также будет наблюдаться с помощью SomethingElse, и когда он будет установлен в NO, тогда все, наблюдающие за TekkPoint, удалят себя как наблюдателя.

Ответ 2

Вы вызываете [super dealloc], прежде чем удалять своих наблюдателей? Вызов super dealloc слишком рано может привести к ошибке, подобной этой.

Ответ 3

зачем вы звоните

[super dealloc]

Из документации Apple на dealloc

In an implementation of dealloc, do not invoke the superclass’s implementation

Ответ 4

Нормальный код выглядит примерно так:

- (void) dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [super dealloc];
}

Дважды проверьте свою подпись своего метода dealloc (Objective C очень неумолимо и никогда не предупредит вас, когда вы испортите имя метода). Например, если ваше имя метода было "dealoc" (с одним l), ваш dealloc никогда не будет вызван.

В противном случае отредактируйте свой вопрос, чтобы включить релонт dealloc.