问题描述
我有一个KVO-able类(称为Observee
),该类的affectedValue
动态属性受affectingValue
属性的影响.属性之间的依赖关系是通过实现+keyPathsForValuesAffectingAffectedValue
方法定义的.
I have a KVO-able class (call it Observee
), which affectedValue
dynamic property is affected by affectingValue
property. The dependency between the properties is defined by implementing +keyPathsForValuesAffectingAffectedValue
method.
将值设置为affectingValue
会通知affectedValue
已按我的预期进行更改,除非,Ovservee
是NSObjectController
的子类.完整示例如下:
Setting a value to affectingValue
notifies that affectedValue
has changed as I expected, unless Ovservee
is a subclass of NSObjectController
. Full example follows:
@interface Observee : NSObject // or NSObjectController
@property (readonly, strong, nonatomic) id affectedValue;
@property (strong, nonatomic) id affectingValue;
@property (strong, nonatomic) NSArrayController *arrayController;
@end
@implementation Observee
@dynamic affectedValue;
- (id)affectedValue { return nil; }
+ (NSSet *)keyPathsForValuesAffectingAffectedValue {
NSLog(@"keyPathsForValuesAffectingAffectedValue called");
return [NSSet setWithObject:@"affectingValue"];
}
@end
@interface AppDelegate : NSObject <NSApplicationDelegate>
@property (strong, nonatomic) Observee *observee;
@end
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)notification {
self.observee = [[Observee alloc] init];
[self.observee addObserver:self
forKeyPath:@"affectedValue"
options:NSKeyValueObservingOptionNew
context:NULL];
NSLog(@"setting value to affectingValue");
self.observee.affectingValue = @42;
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
NSLog(@"affected key path = %@", keyPath);
}
@end
该示例工作正常,并且当Observee
派生NSObject
时,输出如下:
The example works fine and outputs as the following when Observee
derives NSObject
:
keyPathsForValuesAffectingAffectedValue called
setting value to affectingValue
affected key path = affectedValue
,但是当Observee
派生NSObjectController
时:
keyPathsForValuesAffectingAffectedValue called
setting value to affectingValue
(请注意,受影响的键路径=受影响的值"不存在.)
(note that "affected key path = affectedValue" is absent.)
在这两种情况下似乎都调用了keyPathsForValuesAffectingAffectedValue
,但在后一种情况下却没有操作.
It seems that keyPathsForValuesAffectingAffectedValue
is called in both cases but it is no-op in the latter.
此外,任何涉及NSObjectController
(的子类)实例的键路径都不会影响其他键路径,例如:
Also, any key paths involving an instance of (subclass of) NSObjectController
won't affect other key paths, such as:
@implementation SomeObject
// `someValue` won't be affected by `key.path.(snip).arrangedObjects`
+ (NSSet *)keyPathsForValuesAffectingSomeValue {
return [NSSet setWithObject:@"key.path.involving.anNSArrayController.arrangedObjects"];
}
@end
在这种情况下如何声明关键路径之间的依赖关系?而且,为什么这整个事情都在发生?
How do I declare dependency between key paths in such cases? And, why is this whole thing happening?
(是的,我认识will/didChangeValueForKey:
和朋友,但是用(另一个)设置器来封装所有影响键的路径很糟糕,我想避免这种情况.)
(Yes, I know about will/didChangeValueForKey:
and friends, but wrapping up every affecting key path with a(nother) setter is terrible and I'd like to avoid it.)
推荐答案
NSController
及其子类充满KVO黑魔法"和意外行为. (对于另一个示例,它们不尊重某些像NSKeyValueObservingOptionPrior
这样的KVO选项.)如果您期望它们在KVO方面表现得像正常"对象,您将感到失望.它们的存在主要是为了支持可可结合.尽管乍一看绑定似乎只不过是KVO上的语法糖,但您可以看到(通过覆盖绑定对象的KVO支持方法并在其中设置断点),实际上,幕后花了很多功夫而不是简单的KVO观测.
NSController
and its subclasses are full of KVO "black magic" and unexpected behaviors. (For another example, they don't respect certain KVO options like NSKeyValueObservingOptionPrior
) You will be disappointed if you expect them to behave like "normal" objects with respect to KVO. They exist primarily to support Cocoa bindings. Although at first glance bindings may look like mere syntactic sugar on top of KVO, you can see (by overriding the KVO supporting methods of a bound-to object and setting breakpoints in them) that there's actually quite a bit more going on underneath the covers than a simple KVO observation.
请向Apple提交错误,以增加他们修复(或至少记录)此类错误的可能性问题/行为.
Please file bugs with Apple to increase the likelihood that they'll fix (or at least document) these sorts of issues/behavior.
这篇关于KVO:+ keyPathsForValuesAffecting< Key>不适用于NSObjectController(的子类)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!