在我创建的应用程序中,我有一个包含最近文档列表的欢迎窗口(功能类似于新的Xcode 4的欢迎窗口)。我在欢迎窗口中为发布的NSWindowWillCloseNotification注册了应用程序的委托和视图控制器。不幸的是,只有应用程序委托方才收到此事件的通知。

我尝试了以下操作,所有操作都具有相同的行为(不通知窗口控制器):


删除AppDelegate的通知注册代码,希望它以某种方式“消耗”了通知。
将视图控制器上的方法更改为-(void)windowIsClosing:,使其与应用程序委托的名称不同(虽然很远,但是我不得不尝试)
addObserver:...调用在ViewController中移动到代码中的其他位置(因此,如果有问题,在初始化期间不会调用它)。
我确实在通知中心的dealloc方法期间从视图中心注销了我的视图控制器,但是我确保在关闭窗口后而不是在关闭窗口后调用dealloc方法。


我还尝试侦听其他事件,例如委托和控制器中的NSWindowWillMoveNotification,然后再次通知委托但不通知视图控制器。我的视图控制器不是第一响应者链的一部分,但这无关紧要,因为我正在注册的通知是不希望处理针对零目标的操作。

因此,为什么我的控制器没有收到窗口关闭事件的通知,而我的应用程序委托却被告知了?

相关代码如下。
应用程序委托:

@interface AppDelegate : NSObject <NSApplicationDelegate> {
}
@end

@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(windowClosing:)
                                                 name:NSWindowWillCloseNotification
                                               object:nil];
    // other initialization stuff
    [self showWelcomeWindow];
}

- (void)windowClosing:(NSNotification*)aNotification {
    // this method gets called when any window is closing
}
@end


控制器:

@interface ViewController : NSObject {
}
@end

@implementation ViewController
- (id)init {
    self = [super init];
    if (self) {
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(windowClosing:)
                                                     name:NSWindowWillCloseNotification
                                                   object:nil];
    }
    return self;
}

- (void)windowClosing:(NSNotification*)aNotification {
    // this method does not called when window is closing
}
@end

最佳答案

现在,我已经解决了自己的后代问题。

NSNotificationCenter documentation中所述:


  确保在取消分配notificationObserver或在addObserver:selector:name:object:中指定的任何对象之前,调用removeObserver:或removeObserver:name:object:。


ViewController对象正在监听正在关闭的窗口的通知(NSWindowWillCloseNotifications)和我的数据模型对象的通知之一,因此,当我在控制器上设置其他模型对象时,我注销了ViewController的监听被替换的模型对象。

不幸的是,我选择使用removeObserver:方法(该方法也将对象从关闭窗口事件的通知中删除),而不是使用更具体的removeObserver:name:object:从仅对象已注册的通知子集中删除我的控制器。 。回顾代码,在控制器对象有必要被告知除模型之外的任何事件之前,已编写removeObserver

这个故事的寓意是要有一种心理纪律,只在对象的[[NSNotificationCenter defaultCenter] removeObserver:self]调用期间使用dealloc,否则从非常特定的事件中注销(因为您不知道沿途还有什么其他事件通知)也注册)。

关于objective-c - 没有收到NSWindowWillCloseNotifications,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5479543/

10-08 20:56