Notifications和NotificationsCenter的使用

Notifications

Notification包裝了事件的信息, 比如窗口正在獲取焦點或者網絡連接正在斷開. 需要訂閱事件(例如, 一個文件想要知道正在編輯它的窗口將要被關閉)的object需要在notification center註冊, 之後當事件發生的時候就會得到通知. 當事件發生的時候, 一個notification會被髮送到notification center, 而後notification center馬上就會把這個notification轉發給所有訂閱過這個事件的object. 當需要的時候, notification會被緩存在notification queue中….

Notification的原理

在兩個object之間傳遞信息最標準的方法是傳遞消息 – 一個object調用另外一個object的方法. 但是, 傳遞的消息這種方法要求發送消息的object知道消息的接收者和它能接收的消息類型. 這將會把兩個object緊密的綁定起來 – 最值得注意的是這會讓兩個本來獨立的子系統耦合在一起. 爲了解決這些問題, 廣播模型被提了出來. Object只是負責發送notification, 而NSNotificationCenter將負責把這個notification轉發給所有相關的object.

一個NSNotification(在這片文章裏面簡稱notification)包含一個name, 一個object和一個可選的dictionary. Name是notification的標識. Object包含notification發送者想要發送的任意類型的object(一般來說就是發送這個notification的object本身). Dictionary用來保存其他相關的東西(如果有的話).

任意object都可以發送notification. 任意object都可以在notification center註冊以便在某個事件發生的時候能夠得到通知. Notification center負責把接受的notification發送給所有註冊過的消息接收者. 發送notification的object, notification裏面包含的object和接收這個notification的object可以是同一個object, 也可以是三個不同的object. 發送notification的object不需要知道關於接受者的任何信息. 但是, 接受者至少需要知道notification的name和其所包含dictionary的key(如果有的話).

Notification和Delegation

就使用上看, notification系統和delegate很像, 但是他們有以下不同:

*Notification的接受者可以是多個object. 但是delegate object只能有一個. 這就阻止了返回值.
*一個object可以從notification center接受它想要的任意數量個notification, 而delegate只能接受預先定義好的delegate方法.
*發送notification的object完全不知到接受者是否存在.

Notification Centers

Notification center負責接收和發送notification. 當它接受到notification的時候會通知所有符合特定條件的接受者. Notification信息被包裝在NSNotification裏. Notification接收者在notification center裏面註冊以獲得其他object發出的notification. 當事件發生的時候, 一個object發送相關的notification到notification center. Notification center將消息分發給每一個註冊過的接受者. 發送notification的object和接受者可能是同一個.

Cocoa包含兩種notification center:

*NSNotificationCenter類管理單個進程內部的notification.
*NSDistributedNotificationCenter管理一臺機器上跨進程的notification.

NSNotificationCenter

每一個進程都有一個默認的notification center, 你可以通過訪問 NSNotificationCenter 的 +defaultCenter方法來得到它. 這種類型的notification center負責管理單個進程內部的notification. 如果需要管理同一臺機器上不同進程之間的notification則需要用到NSDistributedNotificationCenter.

Notification center發送notification給接收者的方法是同步的. 也就是說, 當發送一個notification的時候, 除非所有的接收者都接到和處理了這個notification, 否則不會返回. 想要發送異步notification的話就需要用到notification queue了.

在一個多線程應用程序裏, notification總是和發送者處於同一個線程裏, 但是接受者可以在其他線程裏.

NSDistributedNotificationCenter

每一個進程都有一個默認的distributed notification center, 你可以通過訪問 NSDistributedNotificationCenter 的 +defaultCenter方法來得到它. 這種類型的notification center負責管理一臺機器上多個進程之間的notification. 如果需要在多臺機器間通訊的話, 使用distributed objects.

發送一個distributed notification是非常昂貴的. Notification首先會被髮送到一個系統級別的服務器上, 然後在分別分發到每一個註冊過的進程裏. 從發從消息到消息被接受到之間的延遲理論上來說是無限的. 事實上, 如果太多的notification被髮送到服務器上, 那麼服務器上的notification隊列可能會被撐滿, 這就有可能會造成notification的丟失.

Distributed notification會在一個進程的主循環裏被髮送出去. 一個進程必須保證有一個主循環在其內部運行, 例如 NSDefaultRunLoopMode, 然後才能接受到distributed notification. 如果接收進程是多線程的, 那麼notification並不一定會被主線程接受到. 一般來說notification會被分發到主線程的主循環, 但是其他線程一樣可以接收到.

一般類型的notification center可以註冊所有object的notification, 但是 distributed notification center只能註冊字符串類型的notification. 因爲發送者和接受者可能在不同進程裏, notification裏面包含的object不能保證指向同一個object. 所以, distributed notification center只能接受包含字符串類型的notification. Notification會基於字符串來匹配.

NotificationCenter的使用
 

1. 定義一個方法

update

2.訂閱通知

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(update) name:@"update" object:nil]

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

[[NSNotificationCenter defaultCenter] postNotificationName:@"update" object:nil];

----------------------------

虛擬鍵盤顯示和消失的通知

[[NSNotificationCenter defaultCenter] addObserver:self

selector:@selector(keyboardWasShown:)

name:UIKeyboardDidShowNotification

object:nil];

[[NSNotificationCenter defaultCenter] addObserver:self

selector:@selector(keyboardWasHidden:)

name:UIKeyboardDidHideNotification

object:nil];

------

- (void)keyboardWasShown:(NSNotification *) aNotification{

if(keyboardShown)

return;

NSDictionary *info = [aNotification userInfo];//獲取通知信息

//get the size of the keyboard.

NSValue *aValue = [info objectForKey:UIKeyboardFrameBeginUserInfoKey];

CGSize keyboardSize = [aValue CGRectValue].size;

//Resize the scroll view

CGRect viewFrame = [scrollView frame];

viewFrame.size.height -= keyboardSize.height;

//Scroll the active text field into view

CGRect textFieldRect = [activeField frame];

[scrollView scrollRectToVisible:textFieldRect animated:YES];

keyboardShown = YES;

}

//Called when the UIKeyboardDidHideNotification is sent

- (void)keyboardWasHidden:(NSNotification *) aNotification{

NSDictionary *info = [aNotification userInfo];

//Get the size of the keyboard.

NSValue *aValue = [info objectForKey:UIKeyboardFrameEndUserInfoKey];

CGSize keyboardSize = [aValue CGRectValue].size;

//Reset the height of the scroll view to its original value

CGRect viewFrame = [scrollView Frame];

viewFrame.size.height += keyboardSize.height;

scrollView.frame = viewFrame;

keyboardShown = NO;

}


/**************************************************************************/

http://www.devdiv.com/home.php?mod=space&uid=82357&do=blog&id=3835

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章