没有收到NSWindowWillCloseNotifications

时间:2011-03-29 22:10:24

标签: objective-c cocoa macos

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

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

  • 删除AppDelegate的通知注册码,希望以某种方式“消费”通知。
  • 将视图控制器上的方法更改为-(void)windowIsClosing:,使其与应用程序委托的名称不同(相当长镜头,但我必须尝试)
  • 将ViewController中的addObserver:...调用移动到代码中的其他位置(因此在初始化程序期间不会调用它,如果某种程度上重要的话)。
  • 我在dealloc方法期间从通知中心取消注册我的视图控制器,但我确保在窗口关闭后不是在关闭期间调用dealloc方法。

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

因此,为什么我的控制器没有收到窗口关闭事件的通知,但我的应用代表是?

相关代码如下...... App代表:

@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

2 个答案:

答案 0 :(得分:6)

现在回答我自己的后代问题,我已经弄明白了。

NSNotificationCenter documentation中所述:

  

确保调用removeObserver:或removeObserver:name:object:在notificationObserver或addObserver中指定的任何对象之前:selector:name:object:is deallocated。

ViewController对象正在侦听正在关闭(NSWindowWillCloseNotifications)的窗口以及我的一个数据模型对象通知的通知。因此,当我在控制器上设置不同的模型对象时,我正在取消注册ViewController从侦听被替换的模型对象。

不幸的是,我选择使用removeObserver:方法(也删除了对象不被通知窗口关闭事件)而不是更具体的removeObserver:name:object:来删除我的控制器只有一部分对象已注册的通知。回顾代码,removeObserver是在控制器对象需要通知来自模型以外的任何事件之前编写的。

故事的道德是让心理训练只在对象的[[NSNotificationCenter defaultCenter] removeObserver:self]调用期间使用dealloc,否则从非常具体的事件中取消注册(从那以后)你不可能知道该对象将注册的其他事件通知。)

答案 1 :(得分:0)

如果您想查看最近使用过的文档,可以继承NSDocumentController并实施-noteNewRecentDocumentURL:;然后Cocoa会在更新进入File&gt;的相同列表时通知您。打开最近。