我有一个KVO-able类(称之为Observee
),affectedValue
动态属性受affectingValue
属性的影响。通过实现+keyPathsForValuesAffectingAffectedValue
方法来定义属性之间的依赖关系。
将值设置为affectingValue
会通知affectedValue
已按预期更改,除非 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
(请注意,“受影响的密钥路径= 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:
和朋友,但是用一个(其他)设置器包围每个影响关键路径都很可怕,我想避免它。)
答案 0 :(得分:6)
NSController
及其子类充满了KVO“黑魔法”和意外行为。 (另一个例子,他们不尊重某些KVO选项,如NSKeyValueObservingOptionPrior
)如果您希望它们表现得像KVO的“正常”对象,您会感到失望。它们主要用于支持Cocoa绑定。虽然乍一看绑定可能看起来只是KVO之上的语法糖,你可以看到(通过覆盖绑定对象的KVO支持方法并在其中设置断点),实际上在封面下面还有更多的内容而不是简单的KVO观察。
请file bugs with Apple增加他们修复(或至少记录)这些问题/行为的可能性。