设置
我有一个 NSTreeController
子类。它有一个名为 selectedProject
的属性,该属性是自定义的,并在 header 中声明如下:
@property (nonatomic, readonly) LPProject *selectedProject;
在私有(private)实现中像这样:
@property (nonatomic, readwrite, assign) LPProject *selectedProject;
至关重要的是,在我在 TreeController 中修改 selectedProject
的每一点,我都会检查生成的 setter/getter。我从不直接修改 iVar。
基本上,这个属性存在的原因是因为 NSTreeController
的正常 selectedObjects
和 selection
属性没有输入,因为我知道这一点TreeController 将始终只管理 LPProject 对象,并且一次只能选择一个项目,我想要使用一个干净的 iVar,而不是不断获取 selectedObjects,检查是否有一个,获取数组中的第一个对象,等等
LP项目
LPProject
是 Core Data 的自定义 NSManagedObject
子类。它有一个名为enabled
的属性。该属性是一个 BOOL,由 NSNumber 表示。它的 getter/setter 是由 Xcode 生成的。
问题
在几个 Controller 中,我尝试观察 selectedProject
对象的 enabled
属性,如下所示:
[_myTreeController addObserver:self
forKeyPath:@"selectedProject.enabled"
options:0
context:NULL];
我已经验证,当 selectedProject
更改时(并且因此 selectedProject.enabled
更改),KVO 通知会到达。但是,当仅 selectedProject
的 enabled
属性发生更改时(即所选项目本身保持不变),KVO 通知不会到达.
但是,如果我以这种方式订阅:
[_myTreeController addObserver:self
forKeyPath:@"selection.enabled"
options:0
context:NULL];
它工作得很好。当 enabled
发生变化并且 selectedProject
保持不变时,KVO 通知就会到达。
我对此感到困惑,因为 selectedProject
是 KVO 兼容的,我觉得 .enabled
的 key 路径应该可以工作。
有人能解释一下吗?我错过了什么?
最佳答案
我不知道您如何以及何时更新 selectedProject
属性,但是由于基于 selection
的方法按预期工作(并且不仅限于此),我建议您将 selectedProject
作为 selectedObjects
的派生属性(因为 selection
是代理,而 selectedObjects
是 KVO也):
// tell Cocoa which property changes directly affect selectedProject
+ (NSSet*)keyPathsForValuesAffectingSelectedProject {
return [NSSet setWithObject:@"selectedObjects"];
}
- (LPProject*)selectedProject {
// you might need to do some isKindOfClass checks if not all nodes are LPProject
return self.selectedObjects.first;
}
header 属性声明保持不变,如果提供 setter,则不需要实现声明。
这样做的好处是,当 selectedObjects
更改时,运行时将自动向 selectedProject
属性发送 KVO 通知,并且只需最少的粘合代码。
关于objective-c - NSTreeController:自定义属性键路径的 KVO 失败。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35006846/