Ответ 1
[...] можно проверить, действительно ли объект наблюдает, что свойство?
Нет. При работе с KVO вы всегда должны иметь в виду следующую модель:
При создании наблюдения вы несете ответственность за удаление этого точного наблюдения. Наблюдение определяется его контекстом, поэтому контекст должен быть уникальным. При получении уведомлений (и, во Льве, при удалении наблюдателя) вы всегда должны проверять контекст, а не путь.
Лучшая практика обработки наблюдаемых объектов заключается в том, чтобы удалить и установить наблюдение в установщике наблюдаемого объекта:
static int fooObservanceContext;
- (void)setFoo:(Foo *)foo
{
[_foo removeObserver:self forKeyPath:@"bar" context:&fooObservanceContext];
_foo = foo; // or whatever ownership handling is needed.
[foo addObserver:self forKeyPath:@"bar" options:0 context:&fooObservanceContext];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if (context == &fooObservanceContext) {
// handle change
} else {
// not my observer callback
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
- (void)dealloc
{
self.foo = nil; // removes observer
}
При использовании KVO вы должны убедиться, что оба объекта, наблюдатель и наблюдатель живы, пока наблюдение находится на месте.
При добавлении наблюдения вы должны сбалансировать это с помощью одного удаления одного и того же наблюдения. Не предполагайте, что вы единственный, кто использует KVO. Классы Framework могут использовать KVO для своих целей, поэтому всегда проверяйте контекст в обратном вызове.
Один последний вопрос, который я хотел бы указать: Наблюдаемое свойство должно соответствовать требованиям KVO. Вы не можете просто наблюдать что-либо.