我很确定,这会起作用,因为很难让它不起作用。
让我们想象一下,您有三个外部(= 不同的对象)属性观察者。
发生什么了:
A. KVO 的开门是一个消息 didChangeValueForKey: 给被观察的对象。如果您打开了自动 KVO,则在调用键的设置器时会自动发送此消息。(这是在一个动态生成的子类中完成的,它会覆盖 setter。)
B. 然后触发 KVO 代码,在语义上看起来像这样:(并且它被简化为仅支持键,但不支持键路径。)
NSSet *observers = kvoBucket[key];
for( id observer in observers )
{
[observer observeValue:[self valueForKey:key] forKeyPath:key …]
}
C. 对于影响键,必须有第二个循环,通知相关属性的变化。(我假设这个列表是在初始化类对象或添加观察时生成的。)
// Inform observers
NSSet *observers = kvoBucket[key];
for( id observer in observers )
{
[observer observeValue:[self valueForKey:key] forKeyPath:key …]
}
// Scan for affected properties
NSSet *keyOfaffectedProperties = affectedPropertiesBucket[key];
for( NSString *key in keyOfaffectedProperties )
{
// trigger kvo for affected property
}
不,让我们坐在开发者的椅子上。他可以将第一个循环复制到第二个循环中。在这种情况下,它不起作用。但这是重复的代码。(而且真正的代码肯定更复杂。)他为什么要这样做?我们每个人都会说:我已经有了这个代码!让我们再次使用它:
- (void)informOberserversForChangeOfKey:(NSString*)key
// Inform observers
NSSet *observers = kvoBucket[key];
for( id observer in observers )
{
[observer observeValue:[self valueForKey:key] forKeyPath:key …]
}
// Scan for affected properties
NSSet *keyOfaffectedProperties = affectedPropertiesBucket[key];
for( NSString *keyOfAffectedProperty in keyOfaffectedProperties )
{
[self informObserversForChangeOfKey:keyOfAffectedProperty];
}
如果没有优化,这使得递归变得不可能或不方便,它应该可以工作。我敢打赌它会奏效——但只有一小笔钱。;-)