1

我正在阅读 Apple 的 Key-Value Observing guide,它没有详细解释一点。

我的问题是:假设我有一个name依赖于firstNameand的属性lastName,并且我还有另一个group依赖于nameand的属性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];
}

请注意,groupname都是计算的只读属性。

4

3 回答 3

2

如果您的问题意味着...

可以keyPathsForValuesAffecting<key>链接到通过几个依赖属性间接影响键吗?

……那么答案是肯定的。

编辑:Apple 的文档确认keyPathsForValuesAffectingValueForKey:支持间接相关通知。

您的最后一条评论似乎表明您希望在直接更改 ivar 时发送 KVO 通知(间接或不)。事实并非如此。KVO 依赖于使用正确的设置器或通过发送手动宣布更改will/didChangeValueForKey:

于 2013-06-27T18:36:16.677 回答
0

我很确定,这会起作用,因为很难让它不起作用。

让我们想象一下,您有三个外部(= 不同的对象)属性观察者。

发生什么了:

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];
}

如果没有优化,这使得递归变得不可能或不方便,它应该可以工作。我敢打赌它会奏效——但只有一小笔钱。;-)

于 2013-06-28T04:56:29.150 回答
0

这里的大多数人都有正确的想法,但为了确认这一点,我已经建立了一个测试项目,其代码与我的问题中提到的完全相同。

结果:它适用于两种方式。

于 2013-06-28T08:46:28.760 回答