我有一个NSViewController
子类,带有一个方便的方法来像这样返回窗口控制器
@interface ILViewController : NSViewController
- (ILWindowController *)windowController;
@end
@implementation ILViewController
- (NSWindowController *)windowController {
return self.view.window.windowController;
}
- (void)setView:(NSView *)view {
[self willChangeValueForKey:@"windowController"];
[super setView:view];
[self didChangeValueForKey:@"windowController"];
}
@end
窗口控制器有一个名为NSString *
的{{1}}属性,我试图通过视图控制器绑定它。但是,我在运行时收到此错误。
mainStatus
为什么会这样?我已适当发送了KVO通知。
以下代码使用了ivar并且实际上不符合KVO,结果不会导致任何错误....
Cannot update for observer <NSAutounbinderObservance 0x1005cf990> for the key path
"windowController.mainStatus" from <ILViewController 0x1001976b0>, most likely because
the value for the key "windowController" has changed without an appropriate KVO
notification being sent. Check the KVO-compliance of the ILViewController class.
这让我感到困惑......有人能看出为什么第一个实现不符合KVO吗?
修改
知道了,如果在为ViewController设置视图后将视图添加到窗口,那么视图的窗口确实在没有适当的KVO通知的情况下被更改。但是,当我尝试观察视图窗口的窗口控制器时,我遇到了这样的错误
@interface ILViewController : NSViewController {
ILWindowController *_windowController;
}
- (ILWindowController *)windowController;
@end
@implementation ILViewController
- (NSWindowController *)windowController {
return _windowController;
}
- (void)setView:(NSView *)view {
[super setView:view];
_windowController = view.window.windowController;
}
@end
因此,如果您无法观察视图窗口,那么当视图窗口发生变化时,必须要有一些方法可以得到通知。有谁知道怎么做?
此外,这些仍然无法解释为什么使用没有KVO通知的iVar的第二版代码实际上有效。
答案 0 :(得分:4)
如果您设置了视图,然后将视图添加到窗口,那么windowController
将更改,而不会发送KVO通知。您需要观察自己的视图window
,并在发生变化时发出意愿/更改通知(可能是自动密钥路径依赖的东西为您做了这个,我不记得它是否真的适用于路径或只是值)。同样,如果窗口的windowController
发生变化,那么您将遇到同样的问题。
修改:此方法称为-automaticallyNotifiesObserversForKey:
。我倾向于说它不支持关键路径,因此您必须自己进行手动观察/通知。
答案 1 :(得分:0)
KVO autonotifying仅支持-set:返回void的方法
未声明某些方法,您的编译器可能会考虑其返回ID并继续。