Ответ 1
Вам нужно использовать -removeObserver:forKeyPath:
для удаления наблюдателя до запуска -[NSObject dealloc]
, так что да, выполнение этого в методе -dealloc
вашего класса будет работать.
Лучше, чем это было бы иметь детерминированный момент, когда все, что принадлежит объекту, который выполняет наблюдение, может сказать, что оно сделано, и будет (в конечном счете) освобождено. Таким образом, вы можете прекратить наблюдение сразу же, когда вещь, выполняющая наблюдение, больше не нужна, независимо от того, когда она фактически освобождена.
Это важно иметь в виду, потому что время жизни объектов в Cocoa не так детерминировано, как кажется некоторым людям. Различные каркасы Mac OS X будут отправлять ваши объекты -retain
и -autorelease
, продлевая срок их службы за пределы того, что вы могли бы подумать, что это будет.
Кроме того, когда вы делаете переход на сборку мусора Objective-C, вы обнаружите, что -finalize
будет работать в самые разные моменты времени - и в самых разных контекстах, чем -dealloc
. Во-первых, финализация происходит в другом потоке, поэтому вы действительно не можете безопасно отправлять -removeObserver:forKeyPath:
другому объекту в методе -finalize
.
Придерживайтесь управления памятью (и другого ограниченного ресурса) в -dealloc
и -finalize
и используйте отдельный метод -invalidate
, чтобы владелец сообщил об этом объект, который вы сделали с ним в детерминированной точке; делайте такие вещи, как удаление наблюдений KVO. Цель вашего кода будет более понятной, и у вас будет меньше тонких ошибок, чтобы позаботиться.