2012-01-12 61 views
0

我有一个NSViewController子类有一个方便的方法返回窗口控制器这样为什么此代码不符合KVO标准?

@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通知。

下面的代码,它使用伊娃,实际上是不符合志愿原来不会导致任何错误....

@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?

编辑

明白了,如果视图被添加到窗口设置完成后的视图控制器再没有适当的志愿通知确实改变视图的窗口。然而,当我尝试观察视图的窗口的窗口控制,我越来越喜欢这个

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的代码的第二版本实际上工作。

+0

您不需要在兼容KVC的setter中发送KVO通知。除非你明确地告诉它,KVO将包装任何这样的setter并发送通知给你。 – 2012-01-12 08:51:51

+0

我正在发送KVO通知,以获取所设置属性的不同属性。 – Tony 2012-01-12 17:11:53

+0

你仍然不需要自己发送KVO通知。相反,实现'keyPathsForValuesAffectingWindowController',并返回一个集合,其唯一对象是'@“view”'。 – 2012-01-12 19:29:12

回答

4

如果您设置了视图,然后将视图添加到窗口,那么windowController将更改,而不会发送KVO通知。你需要观察你自己的视图的window,并发送更改通知(更改通知)(可能自动键路径依赖的东西为你做这件事,我不记得它实际上是与路径还是只是值)。同样,如果窗口的windowController发生更改,那么您将遇到同样的问题。

编辑:该方法被称为-automaticallyNotifiesObserversForKey:。我倾向于说它不支持关键路径,所以你必须做手动观察/通知自己。

+0

谢谢,虽然观察视图的窗口似乎不起作用,但请参阅原始问题中的编辑。 – Tony 2012-01-12 17:12:43

+0

该方法实际上被称为'+自动忽略观察者关键字:' – 2012-11-06 11:02:10

0

志愿只autonotifying支持-set:方法返回void

一些方法不申报,你的编译器可能会想它的返回ID,然后继续。