Notification的總結

Notification的總結 

 
  • 對象之間通訊的標準方式是發送消息,一個object直接調用另外一個object的方法。前提是你須要知道兩個對象及要發送的消息的內容。並且這樣子耦合度過高,綁定了兩個原本是獨立的object。
  • NSNotification包含 a name, an object, and an optional dictionary
  • Any object may post a notification
  • NSNotificationCenter處理單進程之間的通知
  • NSDistributedNotificationCenter處理單個計算機上不一樣的進程之間的通知。
  • 每一個進程都會建立一個NotificationCenter,這個center經過NSNotificationCenter defaultCenter獲取。
  • NoticiationCenter以同步(非異步,會等待,會阻塞)的方式發送請求,即,當發送通知時,center會一直等待全部的observer都收到而且處理了通知纔會返回到poster。若是須要異步發送通知,請使用notificationQueu
  • 在一個多線程的應用程序中,通知會發送到全部的線程中。
  • 每一個進程都有一個distrubuted notification center, 能夠經過NSDistributedNotificationCenter +defaultCenter 訪問,這個distributed notification center 處理 單個機器不一樣線程之間的通知。若須要不一樣的機器之間通訊,須要使用distrubted object
  • 發送distrubuted notification是很是消耗資源的操做,distrubted notification須要被髮送到系統級別的服務中,而後分發給有object註冊過次通知的進程中,distrubted通知發送以後與收到通知之間的延遲是不肯定的,若是有太多通知發送出去天充滿了系統的sever,則這個distrubuted noification可能會被丟棄。
  • Distributed notifications是經過進程的runloop發送的。要接受distrubuted notifiation,這個進程必須以一般的普通的run loop模式運行,好比NSDefaultRunLoopMode,若是接受的進程是多線程的,那麼就不要期望着通知會發送到主線程,雖然一般distrubuted notification是發送到主線程,可是其餘線程也可能收到通知,。
  • 普統統知包含的object能夠爲object指針,但distrubuted的object必須爲string,由於不一樣的進程中指針是不一樣的。
  • NSNotificationQueue,就像是notification的緩衝池。他有兩個重要的feature,合併notifications以及異步發送通知。
  • NSNotificationQueue一般以FIFO(先進先出)的原則處理通知,當一個notification到了隊列前面是,queue把他發送到notification Center,而後notification center再把他發送到observer。
  • 每一個線程都有一個與notification center相關的queue,你也能夠建立本身的queue,這樣就造成一個center和多個queue。
  • 用NSNotificationQueue’s enqueueNotification:postingStyle: and enqueueNotification:postingStyle:coalesceMask:forModes:的方法,你能夠把通知放到queue裏面異步的發送給線程。吧通知放到queue之後這些方法會馬上返回,不作等待。
  • notification有三種style放到queue, NSPostASAPNSPostWhenIdle, and NSPostNow
  • 能夠經過設置第三個參數來使coalesce,多個下相同的notification在queue裏能夠被合併維一個。
 
儘快發送

NSPostASAP風格進入隊列的通告會在運行循環的當前迭代完成時被髮送給通告中心,若是當前運行循環模式和請求的模式相匹配的話(若是請求的模式和當前模式不一樣,則通告在進入請求的模式時被髮出)。因爲運行循環在每一個迭代過程當中可能進行多個調用分支(callout),因此在當前調用分支退出及控制權返回運行循環時,通告可能被分發,也可能不被分發。其它的調用分支可能先發生,好比定時器或由其它源觸發了事件,或者其它異步的通告被分發了。html

您一般能夠將NSPostASAP風格用於開銷昂貴的資源,好比顯示服務器。若是在運行循環的一個調用分支過程當中有不少客戶代碼在窗口緩衝區中進行描畫,在每次描畫以後將緩衝區的內容刷新到顯示服務器的開銷是很昂貴的。在這種狀況下,每一個draw...方法都會將諸如「FlushTheServer」 這樣的通告排入隊列,並指定按名稱和對象進行聚結,以及使用NSPostASAP風格。結果,在運行循環的最後,那些通告中只有一個被派發,而窗口緩衝區也只被刷新一次。編程

空閒時發送

NSPostWhenIdle風格進入隊列的通告只在運行循環處於等待狀態時才被髮出。在這種狀態下,運行循環的輸入通道中沒有任何事件,包括定時器和異步事件。以NSPostWhenIdle風格進入隊列的一個典型的例子是當用戶鍵入文本、而程序的其它地方須要顯示文本字節長度的時候。在用戶輸入每個字符後都對文本輸入框的尺寸進行更新的開銷是很大的(並且不是特別有用),特別是當用戶快速輸入的時候。在這種狀況下,Cocoa會在每一個字符鍵入以後,將諸如「ChangeTheDisplayedSize」這樣的通告進行排隊,同時把聚結開關打開,並使用NSPostWhenIdle風格。當用戶中止輸入的時候,隊列中只有一個「ChangeTheDisplayedSize」通告(因爲聚結的緣由)會在運行循環進入等待狀態時被髮出,顯示部分也所以被刷新。請注意,運行循環即將退出(當全部的輸入通道都過期的時候,會發生這種狀況)時並不處於等待狀態,所以也不會發出通告。緩存

當即發送

NSPostNow風格進入隊列的通告會在聚結以後,當即發送到通告中心。您能夠在不須要異步調用行爲的時候 使用NSPostNow風格(或者經過NSNotificationCenter的postNotification:方法來發送)。在不少編程環境下,咱們不只容許同步的行爲,並且但願使用這種行爲:即您但願通告中心在通告派發以後返回,以便肯定觀察者對象收到通告並進行了處理。固然,當您但願經過聚結移除隊列中相似的通告時,應該用enqueueNotification...方法,且使用NSPostNow風格,而不是使用postNotification:方法。服務器

 
 
 
//=========================================================================

Notifications網絡

Notification包裝了事件的信息, 好比窗口正在獲取焦點或者網絡鏈接正在斷開. 須要訂閱事件(例如, 一個文件想要知道正在編輯它的窗口將要被關閉)的object須要在notification center註冊, 以後當事件發生的時候就會獲得通知. 當事件發生的時候, 一個notification會被髮送到notification center, 然後notification center立刻就會把這個notification轉發給全部訂閱過這個事件的object. 當須要的時候, notification會被緩存在notification queue中….多線程

Notification的原理app

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

一個NSNotification(在這片文章裏面簡稱notification)包含一個name, 一個object和一個可選的dictionary. Name是notification的標識. Object包含notification發送者想要發送的任意類型的object(通常來講就是發送這個notification的object自己). Dictionary用來保存其餘相關的東西(若是有的話).oop

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

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會基於字符串來匹配.

相關文章
相關標籤/搜索