Objective c KVO:+;KeyPathForvaluesAffecting<;键>;不';不使用NSObjectController的(子类)
我有一个KVO-able类(称之为Objective c KVO:+;KeyPathForvaluesAffecting<;键>;不';不使用NSObjectController的(子类),objective-c,cocoa,key-value-observing,nsarraycontroller,nsobjectcontroller,Objective C,Cocoa,Key Value Observing,Nsarraycontroller,Nsobjectcontroller,我有一个KVO-able类(称之为observeee),它affectedValue动态属性受affectingValue属性的影响。属性之间的依赖关系是通过实现+keypathsforvaluesafectingaffectedvalue方法定义的 将值设置为affectingValue会通知affectedValue已按预期更改,除非Ovservee是NSObjectController的子类。完整示例如下: @interface Observee : NSObject // or NSOb
observeee
),它affectedValue
动态属性受affectingValue
属性的影响。属性之间的依赖关系是通过实现+keypathsforvaluesafectingaffectedvalue
方法定义的
将值设置为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
但是当observeee
派生NSObjectController
时:
keyPathsForValuesAffectingAffectedValue called
setting value to affectingValue
(请注意,“受影响的键路径=受影响的值”不存在。)
似乎在这两种情况下都调用了keypathsforvaluesafectingaffectedvalue
,但在后者中它不是op
此外,任何涉及NSObjectController的(子类)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:和friends,但是用(另一个)setter封装每个影响的关键路径是很糟糕的,我想避免它。)
NSController
及其子类充满了KVO“黑魔法”和意外行为。(另一个例子是,它们不尊重某些KVO选项,如nsKeyValueObservingOptionPrevior
)如果您希望它们在KVO方面表现得像“正常”对象,您会感到失望。它们的存在主要是为了支持Cocoa绑定。虽然乍一看,绑定可能看起来只是KVO之上的语法糖,但您可以看到(通过覆盖绑定到对象的支持KVO的方法并在其中设置断点),实际上,在封面下发生的事情比简单的KVO观察要多得多
请增加他们解决(或至少记录)此类问题/行为的可能性。如果您找到原因,请与他人分享;)我现在正在观察
KVO
的奇怪行为,这些类是由核心数据
实体生成的。您是否尝试过使用+(NSSet*)keypathsforvaluesafectingvalueforkey:(NSString*)来进行验证改为键
?默认的+keypathsforvaluesafectingvalueforkey:
实现只是搜索+keypathsforvaluesafecting
并返回其结果——覆盖它在这里没有任何区别。叹气。这当然可以解释为什么我无法根据我的NSArrayController
属性的selectionIndex
(或selection
)来创建属性。。非常烦人-谢谢你的信息@ipmcc:您是否知道缺少对nsKeyValueObservingOptionPrevior
(顺便说一句,*新选项和*旧选项)的支持是否有文档记录?因为有趣的是,Apple文档声明“此对象完全符合键值编码”@Mojo66,就像许多Cocoa绑定一样,似乎没有文档记录。但是相信我……;)