2011-03-29 77 views
2

在我創建的應用程序中,我有一個包含最近文檔列表的歡迎窗口(與新的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

回答

6

現在我已經想通了回答我自己留給後人的問題。

正如NSNotificationCenter documentation說:

一定要調用removeObserver:或removeObserver:名稱:對象:notificationObserver或在指定的addObserver任何對象之前:選擇:名稱:對象:被釋放。

的視圖控制器對象是聽通知,對於那些關閉窗口(NSWindowWillCloseNotifications)和我的數據模型對象的notifications.Therefore之一,當我控制我已被取消註冊視圖控制器上設置不同的模型對象從傾聽正在被替換的模型對象。

不幸的是,我選擇使用removeObserver:方法(它也從窗口關閉事件的通知中刪除對象),而不是更具體的removeObserver:name:object:將我的控制器僅從對象已註冊的通知子集中移除。回顧代碼,removeObserver是在控制器對象有任何需要通知源自除模型以外的事件的事件之前編寫的。

道德故事的是要有鋼鐵般的紀律對象的dealloc通話過程中只使用[[NSNotificationCenter defaultCenter] removeObserver:self]以及以其他方式從非常具體的事件撤銷註冊(因爲你無法知道下什麼其他的事件通知的對象的道路也將被註冊)。

0

如果你想觀察最近使用過的文件,你可以繼承NSDocumentController並實現;然後Cocoa會通知您何時更新進入「文件」>「最近打開」的相同列表。