我正在阅读Apple的Key-Value Observing指南,并没有详细解释一点。
我的问题是:说我的name
属性取决于firstName
和lastName
,我还有另一个依赖group
的属性name
}和gender
。
按照指南,我写了这个
+ (NSSet *)keyPathsForValuesAffectingName {
return [NSSet setWithObjects:@"lastName",@"firstName",nil];
}
为group
编写相应的方法时,我可以像这样写
+ (NSSet *)keyPathsForValuesAffectingGroup {
return [NSSet setWithObjects:@"name",@"gender",nil];
}
或者我必须添加所有相关属性
+ (NSSet *)keyPathsForValuesAffectingGroup {
return [NSSet setWithObjects:@"firstName",@"lastName",@"gender",nil];
}
请注意,group
和name
都是计算的,只读属性。
答案 0 :(得分:2)
如果您的问题意味着......
可以
keyPathsForValuesAffecting<key>
链接到通过几个相关属性间接影响密钥吗?
...然后答案是肯定的。
编辑:keyPathsForValuesAffectingValueForKey:
Apple's documentation确认支持间接相关通知。
您的上一条评论似乎表明您希望在直接更改ivar时发送KVO通知(间接或非间接)。事实并非如此。 KVO依赖于使用正确的setter或通过发送will/didChangeValueForKey:
答案 1 :(得分:0)
我很确定,这会有效,因为很难让它无效。
让我们想象一下,你有三个属性的外部(=不同对象)观察者。
会发生什么:
一个。 KVO的开门是消息didChangeValueForKey:观察对象。如果您已打开自动KVO,则在调用密钥的setter时会自动发送此消息。 (这是在动态生成的子类中完成的,它会覆盖setter。)
B中。然后触发KVO代码,它在语义上看起来像这样:(它只是为了支持键而不是键路径而简化。)
NSSet *observers = kvoBucket[key];
for( id observer in observers )
{
[observer observeValue:[self valueForKey:key] forKeyPath: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 *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];
}
如果没有优化,这使得递归不可能或不方便,它应该工作。我敢打赌它有效 - 但只有少量的钱。 ; - )
答案 2 :(得分:0)
这里的大多数人都有正确的想法,但为了确认这一点,我已经设置了一个测试项目,其中包含与我的问题中提到的完全相同的代码。
结果:它适用于两种方式。