NSNotificationCenter 的詳細說明

  1. 定義一個方法html

      -(void) update{       } 程序員

2. 對象註冊,並關連消息架構

     [[NSNotificationCenter defaultCenter] 併發

     addObserver:self selector:@selector(update) name:@"update" object:nil]  app

3. 在要發出通知消息的地方ide

     [[NSNotificationCenter defaultCenter] 函數

     postNotificationName:@"update" object:nil];post

具體如何使用 Notifications設計

http://blog.sina.com.cn/s/blog_5df7dcaf0100c0q2.htmlserver

////////////////////////////////////////

第十四章: 使用 Notifications

用戶可能使用RaiseMan並打開了幾個document, 而後他發現紫色的背景顏色實在是不利於閱讀文檔正文. 

因而,他打開Preferences panel修改背景顏色,不過使人失望的是,已經存在的文檔的背景顏色不會跟着改變. 

因而,這個用戶可能會寫信給你告訴你這些. 你也許會回覆:"defualts會在document建立的時候纔讀取,

保存document在打開"實際上,用戶想說明的是他但願程序能立馬刷新已經打開的文檔. 若是這樣,那該怎麼作呢?

咱們須要把全部打開的document用一個list記錄起來麼?

--- 什麼是Notification? ---

這個要求其實也很容易實現. 每一個運行中的application都有一個NSNotificationCenter的成員變量,

它的功能就相似公共欄. 對象註冊關注某個肯定的notification(若是有人撿到一隻小狗,就去告訴我). 

咱們把這些註冊對象叫作 observer. 其它的一些對象會給center發送notifications(我撿到了一隻小狗). 

center將該notifications轉發給全部註冊對該notification感興趣的對象. 咱們把這些發送notification的對象叫作 poster

不少的標準Cocoa類會發送notifications: 在改變size的時候,Window會發送notification; 

選擇table view中的一行時,table view會發送notification;咱們能夠在在線幫助文檔中查看到標準cocoa對象發送的notification

在咱們的例子中,咱們將MyDocumet對象註冊爲observer. 而preference controller在用戶改變color時將發送notification. 

MyDocument在接受到該notification後改變background color

在MyDocument對象釋放前,咱們必須從notification center移除咱們註冊的observer. 通常咱們在dealloc方法中作這件事

-- Notifications 不是什麼 --

當程序員們聽到notification center的時候, 他們可能會聯想到IPC(進程間通信).他們認爲:

"我在一個程序中建立一個observer,而後在另一個程序中發送一個notification". 這個設計沒有辦法工做的, 

notification center容許同一個程序中的不一樣對象通許,它不能跨越不一樣的程序 [Notification 就是設計模 式中的 觀察者模式, 

cocoa爲咱們實現了該模式, 就像Java也有一樣的實現同樣]

 

-- NSNotification 和 NSNotificationCenter

Notification對象很是簡單. 它就是poster要提供給observer的信息包裹. notification對象有兩個重要的成員變量: 

name 和 object. 通常object都是指向poster(爲了讓observer在接受到notification時能夠回調到poster)

因此,notification有兩個方法

    - (NSString *)name

    - (id)object

NSNotificaitonCernter是架構的大腦了.它容許咱們註冊observer對象, 發送notification, 撤銷observer對象註冊

下面是它的一些經常使用方法

+ (NSNotificationCenter *)defaultCenter

返回notification center [類方法,返回全局對象, 單件模式.cocoa的不少的全局對象都是經過相似方法實現]

- (void)addObserver:(id)anObserver

           selector:(SEL)aSelector

               name:(NSString *)notificationName

             object:(id)anObject

註冊anObserver對象:接受名字爲notificationName, 發送者爲anObject的notification. 當anObject發送名字

爲notificationName的notification時, 將會調用anObserver的aSelector方法,參數爲該notification 如圖14.1

. 若是notificationName爲nil. 那麼notification center將anObject發送的全部notification轉發給observer

. 若是anObject爲nil.那麼notification center將全部名字爲notificationName的notification轉發給observer

 

- (void)postNotification:(NSNotification *)notification

發送notification至notification center 如圖14.2

 

- (void)postNotificationName:(NSString *)aName

                      object:(id)anObject

建立併發送一個notification

 

- (void)removeObserver:(id)observer

移除observer

-- 發送一個Notification --

發送notification是其中最簡單的步驟了,因此咱們從它開始實現.當咱們接收到changeBackgroundColor:消息時, 

PreferenceController對象發送一個notification.

 

咱們將notification命名爲@"BNRColorChanged" ,咱們使用一個全局常量來指定.(有經驗的程序員會使用一個前綴,

這樣避免和其餘組件定義的notification混淆)打開PreferenceController.h 添加下面的的外部申明

extern NSString * const BNRColorChangedNotification;

在PreferenceController.m中定義常量

NSString * const BNRColorChangedNotification = @"BNRColorChanged";

在PreferenceController.m修改changeBackgroundColor:方法

- (IBAction)changeBackgroundColor:(id)sender

{

    NSColor *color = [colorWell color];

    NSData *colorAsData =

                  [NSKeyedArchiver archivedDataWithRootObject:color];

    [[NSUserDefaults standardUserDefaults] setObject:colorAsData

                                          forKey:BNRTableBgColorKey];

 

    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];

    NSLog(@"Sending notification");

    [nc postNotificationName:BNRColorChangedNotification object:self];

}

-- 註冊成爲Observer --

要註冊一個observer, 咱們必須提供幾個要數: 要成爲observer的對象;所感興趣的notification的名字;

當notification發送時要調用的方法. 咱們也能夠指定要關注莫個對象的notification.(好比說,咱們須要

關注莫個特定的window的resize的notification)

 

編輯MyDocument類的init方法

- (id)init

{

    if (![super init])

        return nil;

 

    employees = [[NSMutableArray alloc] init];

 

    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];

    [nc addObserver:self

           selector:@selector(handleColorChange:)

               name:BNRColorChangedNotification

             object:nil];

    NSLog(@"Registered with notification center");

    return self;

}

同時在dealloc方法,將MyDocument從notification center中移除

- (void)dealloc

{

    [self setEmployees:nil];

    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];

    [nc removeObserver:self];

    [super dealloc];

}

-- 處理Notification --

當一個notification發生時, handleColorChange:方法將被調用. 目前咱們在方法中簡單的打印一些log.

- (void)handleColorChange:(NSNotification *)note

{

    NSLog(@"Received notification: %@", note);

}

編譯運行程序,看到了咱們想要的log了吧

-- userInfo Dictionary --

notification對象的object變量是poster,若是咱們想要notification對象傳遞更多的信息,

咱們可使用user info dictionary. 每一個notification對象有一個變量叫 userInfo, 它是一個NSDictionary對象,

用來存放用戶但願隨着notification一塊兒傳遞到observer的其它信息. MyDocument將使用它來獲得要改變的color.

在PreferenceController.m添加userInfo

- (IBAction)changeBackgroundColor:(id)sender

{

    NSColor *color = [sender color];

    NSData *colorAsData;

    colorAsData = [NSKeyedArchiver archivedDataWithRootObject:color];

    [[NSUserDefaults standardUserDefaults] setObject:colorAsData

                                          forKey:BNRTableBgColorKey];

 

    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];

    NSLog(@"Sending notification");

    NSDictionary *d = [NSDictionary dictionaryWithObject:color

                                                  forKey:@"color"];

    [nc postNotificationName:BNRColorChangedNotification

                      object:self

                    userInfo:d];

}

在MyDocument.m,從userInfo中讀取到color

- (void)handleColorChange:(NSNotification *)note

{

    NSLog(@"Received notification: %@", note);

    NSColor *color = [[note userInfo] objectForKey:@"color"];

    [tableView setBackgroundColor:color];

}

打開幾個窗口,並改變背景顏色,如今,那些打開的窗口的背景顏色立馬就變了.

-- 思考 --

一般當你將本身的一個對象設置爲cocoa某個標準對象的delegate的時候,你同時或許也對該標準對象的notification感興趣. 

例如,咱們實現一個window的delegate來處理 windowShouldClose: , 咱們也許會對 NSWindowDidResizeNotification

這樣的notification感興趣.

若是一個cocoa標準對象有一個delegate,同時它也發送notification的話, cocoa對象會自動將它的delegate對象註冊

成爲observer來接受接受本身的notification. 若是咱們實現了一個delegate,那麼delegate[也就是咱們的對象]

要怎樣聲明來接受notification呢?[方法的名字是什麼?]

 

方法名字其實很簡單: 以notification名字爲基準, 先將NS前綴去掉,接着將第一個字母改成小寫. 在將後面的Notification去掉,

而後加個冒號:. 例如,爲了能接受到window的NSWindowDidResizeNotification, delegate能夠實現方法:

- (void)windowDidResize:(NSNotification *)aNotification

 

當window改變大小時,這個方法將自動調用. 對於NSWindow,咱們能夠在.h或是幫助文檔中找到相似的notification 

來實現notification方法.

-- 挑戰 --

當程序再也不是active狀態是,讓程序發出beep. 當unactive時,NSApplication會發送

NSApplicationDidResignActiveNotification的notificaiton. 而咱們的AppController是NSApplication的delegate.   

函數NSBeep()能夠用來發出beep聲音

相關文章
相關標籤/搜索