深入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];

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

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

當(dāng)我們添加通知以后,我們就可以發(fā)出通知途蒋,也是通過NSNotificationCenter類的defaultCenter來獲取到通知中心猛遍,然后通過postNotificationName來發(fā)出通知。
這里需要注意的一點(diǎn)就是這樣發(fā)出的通知是同步操作号坡,也就是只有當(dāng)發(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>是一個同步操作驾茴,也就是只有當(dāng)響應(yīng)的通知的代碼執(zhí)行完畢以后,發(fā)出通知的對象的代碼才會繼續(xù)往下執(zhí)行氢卡。那么<code> NSNotificationQueue</code>就有一些區(qū)別锈至,他有兩個非常重要的特點(diǎn):即通告的聚結(jié)和異步發(fā)送。聚結(jié)是把和剛進(jìn)入隊(duì)列的通告相類似的其它通告從隊(duì)列中移除的過程译秦。如果一個新的通告和已經(jīng)在隊(duì)列中的通告相類似峡捡,則新的通告不進(jìn)入隊(duì)列,而所有類似的通告(除了隊(duì)列中的第一個通告以外)都被移除筑悴。然而们拙,您不應(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來獲取到這個通知隊(duì)列射沟,然后調(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風(fēng)格進(jìn)入隊(duì)列的通告會在運(yùn)行循環(huán)的當(dāng)前迭代完成時被發(fā)送給通告中心,如果當(dāng)前運(yùn)行循環(huán)模式和請求的模式相匹配的話(如果請求的模式和當(dāng)前模式不同摔刁,則通告在進(jìn)入請求的模式時被發(fā)出)挥转。由于運(yùn)行循環(huán)在每個迭代過程中可能進(jìn)行多個調(diào)用分支(callout),所以在當(dāng)前調(diào)用分支退出及控制權(quán)返回運(yùn)行循環(huán)時共屈,通告可能被分發(fā)绑谣,也可能不被分發(fā)。其它的調(diào)用分支可能先發(fā)生拗引,比如定時器或由其它源觸發(fā)了事件借宵,或者其它異步的通告被分發(fā)了。

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

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

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

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

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末久脯,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子镰吆,更是在濱河造成了極大的恐慌帘撰,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件万皿,死亡現(xiàn)場離奇詭異摧找,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)牢硅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進(jìn)店門蹬耘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人减余,你說我怎么就攤上這事综苔。” “怎么了位岔?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵如筛,是天一觀的道長。 經(jīng)常有香客問我抒抬,道長杨刨,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任瞧剖,我火速辦了婚禮拭嫁,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘抓于。我一直安慰自己做粤,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布捉撮。 她就那樣靜靜地躺著怕品,像睡著了一般。 火紅的嫁衣襯著肌膚如雪巾遭。 梳的紋絲不亂的頭發(fā)上肉康,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天,我揣著相機(jī)與錄音灼舍,去河邊找鬼吼和。 笑死,一個胖子當(dāng)著我的面吹牛骑素,可吹牛的內(nèi)容都是我干的炫乓。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼末捣!你這毒婦竟也來了侠姑?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤箩做,失蹤者是張志新(化名)和其女友劉穎莽红,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體邦邦,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡安吁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了圃酵。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片柳畔。...
    茶點(diǎn)故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖郭赐,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情确沸,我是刑警寧澤捌锭,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站罗捎,受9級特大地震影響观谦,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜桨菜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一豁状、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧倒得,春花似錦泻红、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至菩彬,卻和暖如春缠劝,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背骗灶。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工惨恭, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人耙旦。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓脱羡,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子轻黑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評論 2 345

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