我有一个支持 KVO 的类(称之为 Observee
),affectedValue
动态属性受 affectingValue
属性影响。属性之间的依赖关系通过实现+keyPathsForValuesAffectingAffectedValue
方法来定义。
设置一个值给affectingValue
通知affectedValue
已经按照我的预期改变了,unless Ovservee
是一个子类的 NSObjectController
。完整示例如下:
@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
时,该示例工作正常并输出如下:
keyPathsForValuesAffectingAffectedValue called
setting value to affectingValue
affected key path = affectedValue
但是当 Observee
派生 NSObjectController
时:
keyPathsForValuesAffectingAffectedValue called
setting value to affectingValue
(注意“affected key path = affectedValue”不存在。)
似乎在这两种情况下都调用了 keyPathsForValuesAffectingAffectedValue
,但在后者中它是空操作。
此外,任何涉及 NSObjectController
实例(子类)的关键路径都不会影响其他关键路径,例如:
@implementation SomeObject
// `someValue` won't be affected by `key.path.(snip).arrangedObjects`
+ (NSSet *)keyPathsForValuesAffectingSomeValue {
return [NSSet setWithObject:@"key.path.involving.anNSArrayController.arrangedObjects"];
}
@end
在这种情况下,如何声明关键路径之间的依赖关系?而且,为什么会发生这一切?
(是的,我知道 will/didChangeValueForKey:
和 friend ,但是用(另一个)setter 包裹每个影响关键路径是很糟糕的,我想避免它。)
最佳答案
NSController
及其子类充满了 KVO“黑魔法”和意想不到的行为。 (再举一个例子,它们不遵守某些 KVO 选项,例如 NSKeyValueObservingOptionPrior
)如果您希望它们在 KVO 方面表现得像“普通”对象,您将会感到失望。它们的存在主要是为了支持 Cocoa 绑定(bind)。虽然乍一看绑定(bind)可能看起来只是 KVO 之上的语法糖,但您可以看到(通过覆盖绑定(bind)对象的 KVO 支持方法并在其中设置断点)实际上在幕后还有很多事情要做而不是简单的 KVO 观察。
请file bugs with Apple以增加他们解决(或至少记录)这类问题/行为的可能性。
关于objective-c - KVO : +keyPathsForValuesAffecting<Key> doesn't work with (subclass of) NSObjectController,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15966158/