深入NSNotification(iOS)

NSNotification顧名思義就是通知的作用,一個對象通知另外一個對象,可以用來傳遞參數(shù)、通信等作用,與delegate的一對一不同,通知是一對多的。在一個對象中注冊了通知,那么其他任意對象都可以來對這個對象發(fā)出通知。
這篇文章主要講訴兩個對象

  • NSNotificationCenter
  • NSNotificationQueue

1、NSNotificationCenter

    /**
     *  注冊一個通知
     *
     */
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getNotification:) name:@"notificationMethon" object:nil];

NSNotificationCenter是一個單列,我們可以通過defaultCenter來獲取到通知中心這個單列,使用通知的第一步就是添加通知。

 /**
     *  移除所有通知
     */
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    /**
     *  移除單個通知
     *
     */
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"notificationMethon" object:nil];

需要注意的是當我們添加一個通知以后,必須在合適的位置將通知移除,不然下次再添加這個通知并調(diào)用時,這個通知將會被調(diào)用多次,而這一般不是我們所預(yù)料的。一般我們在對象的析構(gòu)函數(shù)中將通知移除,我們可以選擇將這個對象中的所有通知移除,也可以選擇一個一個按照通知的name來移除。

    /**
     *  發(fā)出通知
     */
    [[NSNotificationCenter defaultCenter] postNotificationName:@"notificationMethon" object:nil userInfo:@{@"key":@"value"}];

當我們添加通知以后,我們就可以發(fā)出通知,也是通過NSNotificationCenter類的defaultCenter來獲取到通知中心,然后通過postNotificationName來發(fā)出通知。
這里需要注意的一點就是這樣發(fā)出的通知是同步操作,也就是只有當發(fā)出的通知執(zhí)行完畢以后才會繼續(xù)執(zhí)行接下去的代碼。

-(void)getNotification:(NSNotification *)info{
    NSDictionary *dict = info.userInfo;
}

這是發(fā)出通知以后會調(diào)用的方法,在多線程操作時,發(fā)出通知的對象和接收通知的對象處于同一個線程。
在這個響應(yīng)的方法中有一個參數(shù)<code>(NSNotification *)info</code>這個參數(shù)是NSNotification類型的,這個類型有幾個屬性:

@property (readonly, copy) NSString *name;
@property (nullable, readonly, retain) id object;
@property (nullable, readonly, copy) NSDictionary *userInfo;

其中<code> userInfo </code>這個屬性是一個字典,也是最為關(guān)鍵以及有用的屬性,我們通過這個屬性來傳遞參數(shù)等一些有用的信息。

總結(jié)以上內(nèi)容,所以通知的最簡單的使用過程就是:
1、添加通知;
2、發(fā)出通知;
3、移除通知;


2、NSNotificationQueue

上面說到<code> NSNotificationCenter</code>是一個同步操作,也就是只有當響應(yīng)的通知的代碼執(zhí)行完畢以后,發(fā)出通知的對象的代碼才會繼續(xù)往下執(zhí)行。那么<code> NSNotificationQueue</code>就有一些區(qū)別,他有兩個非常重要的特點:即通告的聚結(jié)和異步發(fā)送。聚結(jié)是把和剛進入隊列的通告相類似的其它通告從隊列中移除的過程。如果一個新的通告和已經(jīng)在隊列中的通告相類似,則新的通告不進入隊列,而所有類似的通告(除了隊列中的第一個通告以外)都被移除。然而,您不應(yīng)該依賴于這個特殊的聚結(jié)行為。
而異步發(fā)送則很好理解了,也就是說發(fā)出通知以后立刻返回,也就是是繼續(xù)執(zhí)行下面的代碼,并不管通知發(fā)出后的具體情況

/**
     發(fā)出通知
     */
    NSNotification *notifacation = [[NSNotification alloc]initWithName:@"notificationMethon" object:nil userInfo:@{@"key":@"value1"}];
    [[NSNotificationQueue defaultQueue] enqueueNotification:notifacation postingStyle:NSPostWhenIdle];

我們可以通過,NSNotificationQueue的defaultQueue來獲取到這個通知隊列,然后調(diào)用<code>enqueueNotification</code>來發(fā)出通知,我們可以看到第二個參數(shù)<code>postingStyle</code>,這個參數(shù)是一個枚舉,他可以是以下三個值:

typedef NS_ENUM(NSUInteger, NSPostingStyle) {
    NSPostWhenIdle = 1,
    NSPostASAP = 2,
    NSPostNow = 3
};

這三個不同的值是有一定區(qū)別的。(以下內(nèi)容摘抄自網(wǎng)絡(luò))

盡快發(fā)送
以NSPostASAP風格進入隊列的通告會在運行循環(huán)的當前迭代完成時被發(fā)送給通告中心,如果當前運行循環(huán)模式和請求的模式相匹配的話(如果請求的模式和當前模式不同,則通告在進入請求的模式時被發(fā)出)。由于運行循環(huán)在每個迭代過程中可能進行多個調(diào)用分支(callout),所以在當前調(diào)用分支退出及控制權(quán)返回運行循環(huán)時,通告可能被分發(fā),也可能不被分發(fā)。其它的調(diào)用分支可能先發(fā)生,比如定時器或由其它源觸發(fā)了事件,或者其它異步的通告被分發(fā)了。

您通常可以將NSPostASAP風格用于開銷昂貴的資源,比如顯示服務(wù)器。如果在運行循環(huán)的一個調(diào)用分支過程中有很多客戶代碼在窗口緩沖區(qū)中進行描畫,在每次描畫之后將緩沖區(qū)的內(nèi)容刷新到顯示服務(wù)器的開銷是很昂貴的。在這種情況下,每個draw...方法都會將諸如“FlushTheServer” 這樣的通告排入隊列,并指定按名稱和對象進行聚結(jié),以及使用NSPostASAP風格。結(jié)果,在運行循環(huán)的最后,那些通告中只有一個被派發(fā),而窗口緩沖區(qū)也只被刷新一次。

空閑時發(fā)送
以NSPostWhenIdle風格進入隊列的通告只在運行循環(huán)處于等待狀態(tài)時才被發(fā)出。在這種狀態(tài)下,運行循環(huán)的輸入通道中沒有任何事件,包括定時器和異步事件。以NSPostWhenIdle風格進入隊列的一個典型的例子是當用戶鍵入文本、而程序的其它地方需要顯示文本字節(jié)長度的時候。在用戶輸入每一個字符后都對文本輸入框的尺寸進行更新的開銷是很大的(而且不是特別有用),特別是當用戶快速輸入的時候。在這種情況下,Cocoa會在每個字符鍵入之后,將諸如“ChangeTheDisplayedSize”這樣的通告進行排隊,同時把聚結(jié)開關(guān)打開,并使用NSPostWhenIdle風格。當用戶停止輸入的時候,隊列中只有一個“ChangeTheDisplayedSize”通告(由于聚結(jié)的原因)會在運行循環(huán)進入等待狀態(tài)時被發(fā)出,顯示部分也因此被刷新。請注意,運行循環(huán)即將退出(當所有的輸入通道都過時的時候,會發(fā)生這種情況)時并不處于等待狀態(tài),因此也不會發(fā)出通告。

立即發(fā)送
以NSPostNow風格進入隊列的通告會在聚結(jié)之后,立即發(fā)送到通告中心。您可以在不需要異步調(diào)用行為的時候 使用NSPostNow風格(或者通過NSNotificationCenter的postNotification:方法來發(fā)送)。在很多編程環(huán)境下,我們不僅允許同步的行為,而且希望使用這種行為:即您希望通告中心在通告派發(fā)之后返回,以便確定觀察者對象收到通告并進行了處理。當然,當您希望通過聚結(jié)移除隊列中類似的通告時,應(yīng)該用enqueueNotification...方法,且使用NSPostNow風格,而不是使用postNotification:方法。

總結(jié)NSNotificationCenter和NSNotificationQueue的區(qū)別,也許最大的一點就是發(fā)出通知時一個是同步一個是異步。

如果對您有一定幫助,請關(guān)注本人。
(轉(zhuǎn)載請表明出處、作者)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,698評論 6 539
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,202評論 3 426
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,742評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,580評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,297評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,688評論 1 327
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,693評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,875評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,438評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,183評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,384評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,931評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,612評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,022評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,297評論 1 292
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,093評論 3 397
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,330評論 2 377

推薦閱讀更多精彩內(nèi)容