此份文件為個人學習通知中心的翻譯,內文請參考蘋果官方文件,若有翻譯錯誤請見諒,請勿挪作商業用途,並著明出處。
原始文章連結:
http://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Notifications/
NSNotificationQueue物件,或簡單說,通知隊列(notification queues)作為通知中心(NSNotificationCenter的實例)的緩衝區。NSNotificationQueue類別對於Foundation Kit的通知機制而言,有兩個重要的特色:通知的聚合(the coalescing of notification)和非同步貼出(asynchronous posting)。
每一個線程都有預設的通知隊列,隊列與該程序(process)預設的通知中心有關。你可以創建你自己的通知隊列並且在每個中心和線程上有多重的隊列。
注意:當排列通知的線程在通知對列貼出通知到通知中心前就終結時,通知就不會被貼出。參考“Delivering Notifications To Particular Threads”以瞭解如何貼出通知到不同的線程。
通知隊列被清除和它的通知張貼是基於張貼風格(posting style)以及在enqueuing方法中指明的run loop mode。mode引數指明run loop mode,在該run loop mode下隊列將被清除。舉例來說,若你指明NSModalPanelRunLoopMode,通知只有當run loop 是這種mode時才會被貼出。若目前的run loop 不是這種mode,通知會等到下一次那個模式進入時。參考Threading Programming Guide裡面的“Run Loop Modes”。
張貼到通知對列可以發生在下列三種不同的風格中:NSPostASAP、NSPostWhenIdle以及 NSPostNow。下面章節將要介紹這三種風格。
假設目前的run loop匹配要求的mode,當目前的run loop的遞迴完成時,任何有NSPostASAP風格的通知隊列會張貼到通知中心(若要求的mode和目前的不同,通知會等到要求的mode進入後才張貼)。因為在每一次的遞迴中,run loop可以做多重的callout,目前的callout存在並且控制返回到run loop時通知就能或不能被傳遞。其他callout可能會先發生,像是計時器(timer)或是source firing或是其他被傳遞的非同步通知。
最典型的,是對expensive resource使用NSPostASAP張貼風格,像是display server。當run loop裡面於callout期間,許多在視窗上的client draw緩衝,在每次draw operation後去刷新(flush)display server的緩衝很耗能。在這情況下,每一個draw...方法會排列一些通知,像是FlushTheServer,有聚合指定的名稱和物件,以及NSPostASAP的張貼風格。因此,那些通知裡面只有一個會在run loop結束時被派送,而且視窗緩衝(window buffer)只會被刷新(flush)一次。
In this state, there’s nothing in the run loop’s input channels, be it timers or other asynchronous events.(完全被這句打敗...)。
以NSPostWhenIdle風格來列隊的典型例子是,使用者輸入文字,並且程式在某處以字節(bytes)顯示文字的大小。在每一次使用者輸入字符時更新text field size是很耗能(又不是很有用)的事,特別是如果使用者輸入的很快時。在這情況下,程式會排列ChangeTheDisplayedSize通知,是啟動聚合並且在每個字符輸入後張貼風格是NSPostWhenIdle的通知。當使用者停止輸入,(根據聚合)在隊伍中單一的ChangeTheDisplayedSize通知會在run loop進入等待狀態並且顯示被更新時貼出。注意即將要跳出(exit)的run loop(當有所有的input channel失效時會發生)不算是等待狀態,因此不會貼出通知。
(這三段有夠難搞,我來大致歸納一下)
某些情況下,如果一個事件至少會發生一次,你或許想要貼出通知,
原始文章連結:
http://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Notifications/
NSNotificationQueue物件,或簡單說,通知隊列(notification queues)作為通知中心(NSNotificationCenter的實例)的緩衝區。NSNotificationQueue類別對於Foundation Kit的通知機制而言,有兩個重要的特色:通知的聚合(the coalescing of notification)和非同步貼出(asynchronous posting)。
Notification Queue Basics
使用NSNotificationCenter的postNotification:方法和它的變數,你可以貼出一個通知到通知中心。然而,此方法的調用是同步的:在張貼物件(posting object)可以啓動它的執行線程前,它必須等到通知中心派送通知道所有的物件並且返回。另一方面,一般來說通知對列以先進先出(First In First Out, FIFO)的順序保存通知(NSNotification的實例),當一個通知被提升到隊列的最前面時,隊列將它貼到通知中心去,通知中心會把這通知派送到所有註冊為觀察者的物件。每一個線程都有預設的通知隊列,隊列與該程序(process)預設的通知中心有關。你可以創建你自己的通知隊列並且在每個中心和線程上有多重的隊列。
Posting Notifications Asynchronously
使用NSNotificationQueue的enqueueNotification:postingStyle:和enqueueNotification:postingStyle:coalesceMask:forModes:方法,你可以把通知放到隊列中,非同步的貼出通知到目前的線程。放入通知到隊列後,這些方法會立刻返回到調用物件(invoking object)去。通知隊列被清除和它的通知張貼是基於張貼風格(posting style)以及在enqueuing方法中指明的run loop mode。mode引數指明run loop mode,在該run loop mode下隊列將被清除。舉例來說,若你指明NSModalPanelRunLoopMode,通知只有當run loop 是這種mode時才會被貼出。若目前的run loop 不是這種mode,通知會等到下一次那個模式進入時。參考Threading Programming Guide裡面的“Run Loop Modes”。
張貼到通知對列可以發生在下列三種不同的風格中:NSPostASAP、NSPostWhenIdle以及 NSPostNow。下面章節將要介紹這三種風格。
Posting As Soon As Possible
假設目前的run loop匹配要求的mode,當目前的run loop的遞迴完成時,任何有NSPostASAP風格的通知隊列會張貼到通知中心(若要求的mode和目前的不同,通知會等到要求的mode進入後才張貼)。因為在每一次的遞迴中,run loop可以做多重的callout,目前的callout存在並且控制返回到run loop時通知就能或不能被傳遞。其他callout可能會先發生,像是計時器(timer)或是source firing或是其他被傳遞的非同步通知。
最典型的,是對expensive resource使用NSPostASAP張貼風格,像是display server。當run loop裡面於callout期間,許多在視窗上的client draw緩衝,在每次draw operation後去刷新(flush)display server的緩衝很耗能。在這情況下,每一個draw...方法會排列一些通知,像是FlushTheServer,有聚合指定的名稱和物件,以及NSPostASAP的張貼風格。因此,那些通知裡面只有一個會在run loop結束時被派送,而且視窗緩衝(window buffer)只會被刷新(flush)一次。
Posting When Idle
只有當run loop處於等待狀態時, 以NSPostWhenIdle風格的排隊的通知會被貼出。In this state, there’s nothing in the run loop’s input channels, be it timers or other asynchronous events.(完全被這句打敗...)。
以NSPostWhenIdle風格來列隊的典型例子是,使用者輸入文字,並且程式在某處以字節(bytes)顯示文字的大小。在每一次使用者輸入字符時更新text field size是很耗能(又不是很有用)的事,特別是如果使用者輸入的很快時。在這情況下,程式會排列ChangeTheDisplayedSize通知,是啟動聚合並且在每個字符輸入後張貼風格是NSPostWhenIdle的通知。當使用者停止輸入,(根據聚合)在隊伍中單一的ChangeTheDisplayedSize通知會在run loop進入等待狀態並且顯示被更新時貼出。注意即將要跳出(exit)的run loop(當有所有的input channel失效時會發生)不算是等待狀態,因此不會貼出通知。
Posting Immediately
在聚合到通知中心後,以NSPostNow列隊的通知會立刻被貼出。當你不要求非同步呼叫的行為時,你可將
NSPostNow風格的通知列隊(若是以
postNotification:來貼出
)。對很多程式化的情況是,同步行為不只是可允許的也是想要的:你想要通知中心在派送後返回,讓你可以確保觀察物件有接收到並且處理通知。當然,如果隊列中有你想要以聚合來移除的相似的通知,你應該
使用
enqueueNotification...加上
NSPostNow,
而不是使用
postNotification:。
(這三段有夠難搞,我來大致歸納一下)
張貼時機
NSPostNow 立刻
NSPostWhenIdle run loop等待時
NSPostASAP run loop完成時
留言
張貼留言