【发布时间】:2012-01-12 03:58:47
【问题描述】:
我有一个 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
窗口控制器有一个名为mainStatus 的NSString * 属性,我试图通过视图控制器绑定到该属性。但是,我在运行时收到此错误。
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 通知。
以下代码使用 ivar,实际上不符合 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 吗?
编辑
知道了,如果在为 ViewController 设置视图之后将视图添加到窗口,那么视图的窗口确实会在没有适当 KVO 通知的情况下更改。但是,当我尝试观察视图的窗口的窗口控制器时,我遇到了这样的错误
KVO autonotifying only supports -set<Key>: methods that return void. Autonotifying
will not be done for invocations of -[NSView _setWindow:].
Cannot remove an observer <NSKeyValueObservance 0x102e17880> for the key path
"window.windowController.mainStatus" from <NSView 0x102e13ec0>, most likely because
the value for the key "window" has changed without an appropriate KVO notification
being sent. Check the KVO-compliance of the NSView class.
因此,如果您无法观察视图的窗口,那么当视图的窗口发生变化时,肯定有一些方法可以通知您。有人知道怎么做吗?
此外,这些仍然不能解释为什么使用没有 KVO 通知的 iVar 的代码的第二个版本实际上可以工作。
【问题讨论】:
-
您不需要在符合 KVC 的设置器中发送 KVO 通知。 KVO 将包装任何此类设置器并为您发送通知,除非您明确告诉它不要这样做。
-
我正在发送 KVO 通知以获取所设置的属性会影响的不同属性。
-
您仍然不需要自己发送 KVO 通知。相反,实现
keyPathsForValuesAffectingWindowController,并返回一个集合,其唯一的对象是@"view"。 -
是的,我也试过了。在这两种情况下,它仍然不能解决观察视图窗口的问题
-
没有理由这样做。它的作用是让您不必自己实现
-[ILViewController setView:]。
标签: objective-c cocoa binding key-value-observing