没有收到NSWindowWillCloseNotifications

问题描述:

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

我试过以下,都具有相同的行为(窗控制器未收到通知):

  • 卸下AppDelegate中的通知注册代码,希望,不知怎的,这是“消费”的通知。
  • 更改视图控制器上的方法来-(void)windowIsClosing:,使得它是不一样的名称作为应用程序代理(相当长镜头,但我不得不尝试)
  • 移动电话addObserver:...在视图控制器到别的地方在代码中(所以它没有在初始化过程中被调用,如果不知何故重要)。
  • 我在通知中心的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 
+0

视图控制器在什么时候被初始化? – Sam 2011-03-29 22:41:47

+0

@Sam欢迎窗口由NSWindowController的子类引用,并且它们之间的关系在NIB中设置。该NSWindowController对象具有一个ivar,用于初始化ViewController(我已经验证ViewController的 - (id)init方法正在被调用)。 – Peter 2011-03-29 22:46:13

现在我已经想通了回答我自己留给后人的问题。

正如NSNotificationCenter documentation说:

一定要调用removeObserver:或removeObserver:名称:对象:notificationObserver或在指定的addObserver任何对象之前:选择:名称:对象:被释放。

的视图控制器对象是听通知,对于那些关闭窗口(NSWindowWillCloseNotifications)和我的数据模型对象的notifications.Therefore之一,当我控制我已被取消注册视图控制器上设置不同的模型对象从倾听正在被替换的模型对象。

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

道德故事的是要有钢铁般的纪律对象的dealloc通话过程中只使用[[NSNotificationCenter defaultCenter] removeObserver:self]以及以其他方式从非常具体的事件撤销注册(因为你无法知道下什么其他的事件通知的对象的道路也将被注册)。

如果你想观察最近使用过的文件,你可以继承NSDocumentController并实现;然后Cocoa会通知您何时更新进入“文件”>“最近打开”的相同列表。