Когда следует удалять наблюдателей? Ошибка об удалении объектов перед удалением наблюдателей
Я пытаюсь использовать наблюдение за ключевыми значениями в одном из моих классов. Я регистрирую наблюдателей в методе 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];
}
Одно замечание, которое может показаться странным в моей реализации, заключается в том, что я добавляю и удаляю наблюдателей от наблюдателя, может ли это вызвать мою проблему?
Ответы
Ответ 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.