通知NSNotificationCenter詳解(一)

版本記錄

版本號 時間
V1.0 2017.07.17

前言

與代理相比,通知具有低耦合的特點跋核,兩個毫無關(guān)聯(lián)的控制器之間可以進(jìn)行相互通信并相應(yīng)操作薯酝,用了通知很久,但是從沒有系統(tǒng)的總結(jié)一下通知相關(guān)的知識和遇到的坑母截,下面就講一下通知的相關(guān)知識到忽,先從簡單的知識點和API開始。

通知基礎(chǔ)

通知是ios中的一種消息機(jī)制清寇,觀察者只要向消息中心注冊喘漏, 即可接受其他對象發(fā)送來的消息,消息發(fā)送者和消息接受者兩者可以互相一無所知华烟,完全解耦翩迈。這種消息通知機(jī)制可以應(yīng)用于任意時間和任何對象,觀察者可以有多個盔夜,所以消息具有廣播的性質(zhì)负饲,只是需要注意的是,觀察者向消息中心注冊以后喂链,在不需要接受消息時需要向消息中心注銷返十,這種消息廣播機(jī)制是典型的“Observer”(觀察者)模式。

消息機(jī)制常常用于在向服務(wù)器端請求數(shù)據(jù)或者提交數(shù)據(jù)的場景椭微,在和服務(wù)器端成功交互后洞坑,需要處理服務(wù)器端返回的數(shù)據(jù),或發(fā)送響應(yīng)消息等蝇率,就需要用到消息機(jī)制迟杂。其原理主要如下所示:

通知原理

API

下面我們看一下ios中通知相關(guān)的API。

NSNotification

/****************   Notifications   ****************/

@interface NSNotification : NSObject <NSCopying, NSCoding>

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

- (instancetype)initWithName:(NSNotificationName)name object:(nullable id)object userInfo:(nullable NSDictionary *)userInfo NS_AVAILABLE(10_6, 4_0) NS_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER;

@end

@interface NSNotification (NSNotificationCreation)

+ (instancetype)notificationWithName:(NSNotificationName)aName object:(nullable id)anObject;
+ (instancetype)notificationWithName:(NSNotificationName)aName object:(nullable id)anObject userInfo:(nullable NSDictionary *)aUserInfo;

- (instancetype)init /*NS_UNAVAILABLE*/;    /* do not invoke; not a valid initializer for this class */

@end

這里面有幾點:

  • name:通知的名字本慕,其實就是為通知起的別名排拷,作用就是用以區(qū)分不同通知,如果為nil標(biāo)識可以接收任何名字的通知间狂。
  • object :發(fā)送通知的對象攻泼,用以區(qū)分是誰發(fā)出的通知火架,如果為nil鉴象,表示可以接受任何對象發(fā)送的通知忙菠。
  • userInfo:它是一個字典用來存儲發(fā)送的通知信息,當(dāng)我們post一個通知的時候纺弊,就可以存放在字典里面牛欢,add監(jiān)聽端,就可以將這個userInfo取出來淆游,得到通知的內(nèi)容傍睹。
  • 接下里的幾個對象方法和類方法中存儲的就是通知的初始化或者實例化方法。

** NSNotificationCenter**

/****************   Notification Center ****************/

@interface NSNotificationCenter : NSObject {
    @package
    void *_impl;
    void *_callback;
    void *_pad[11];
}

#if FOUNDATION_SWIFT_SDK_EPOCH_AT_LEAST(8)
@property (class, readonly, strong) NSNotificationCenter *defaultCenter;

- (void)addObserver:(id)observer selector:(SEL)aSelector name:(nullable NSNotificationName)aName object:(nullable id)anObject;
#endif

- (void)postNotification:(NSNotification *)notification;
- (void)postNotificationName:(NSNotificationName)aName object:(nullable id)anObject;
- (void)postNotificationName:(NSNotificationName)aName object:(nullable id)anObject userInfo:(nullable NSDictionary *)aUserInfo;

- (void)removeObserver:(id)observer;
- (void)removeObserver:(id)observer name:(nullable NSNotificationName)aName object:(nullable id)anObject;

- (id <NSObject>)addObserverForName:(nullable NSNotificationName)name object:(nullable id)obj queue:(nullable NSOperationQueue *)queue usingBlock:(void (^)(NSNotification *note))block NS_AVAILABLE(10_6, 4_0);
    // The return value is retained by the system, and should be held onto by the caller in
    // order to remove the observer with removeObserver: later, to stop observation.

@end

這里涉及到的就是通知的轉(zhuǎn)發(fā)犹菱、監(jiān)聽以及移除等拾稳,這個后續(xù)會詳細(xì)說明。


通知的發(fā)送

有關(guān)通知發(fā)送的方法主要有三個腊脱,如下:

- (void)postNotification:(NSNotification *)notification;
- (void)postNotificationName:(NSNotificationName)aName object:(nullable id)anObject;
- (void)postNotificationName:(NSNotificationName)aName object:(nullable id)anObject userInfo:(nullable NSDictionary *)aUserInfo;

我們先說一下相關(guān)參數(shù)访得,這里的參數(shù)和注冊觀察者時候的參數(shù)也都是一樣的,說一遍就不多說了陕凹。

  • notification:通知對象悍抑,通知中心發(fā)出的對象就是它。
  • aName:通知的名字杜耙,用以區(qū)分不同通知搜骡,在注冊觀察者的時候,傳nil表示可以監(jiān)聽任何名稱的通知佑女。
  • anObject:發(fā)送通知的對象记靡,如果傳nil表示不關(guān)心是誰發(fā)送的通知,觀察者那邊傳入nil表示可以接受任何發(fā)送者的通知团驱。
  • aUserInfo:通知消息簸呈,是一個字典,發(fā)送的內(nèi)容可以寫在里面店茶。

第一種發(fā)送通知

    //第一種發(fā)送通知
    NSNotification *notification = [NSNotification notificationWithName:@"notificationTestOne" object:self];
    [[NSNotificationCenter defaultCenter] postNotification:notification];
  

這里的object也可以為nil蜕便,表示不區(qū)分是誰發(fā)送的。

第二種發(fā)送通知

    //第二種發(fā)送通知
    [[NSNotificationCenter defaultCenter] postNotificationName:@"notificationTestTwo" object:self];

同上贩幻,就不多說了轿腺。

第三種發(fā)送通知

    //第三種發(fā)送通知
    NSDictionary *notiDict = @{@"key":@"content"};
    [[NSNotificationCenter defaultCenter] postNotificationName:@"notificationTestThree" object:self userInfo:notiDict];

這里,當(dāng)沒有什么傳遞的時候丛楚,userInfo可以為空族壳,為空的時候就和前兩種發(fā)送通知是一樣的了。


通知的監(jiān)聽

通知是一種觀察者模式趣些,有人發(fā)送就要有人observer仿荆,并調(diào)用相關(guān)方法,處理相關(guān)邏輯。下面我們就接受一下上面三種發(fā)送的通知拢操。

第一種監(jiān)聽通知

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(processTestOne:) name:@"notificationTestOne" object:nil];
- (void)processTestOne:(NSNotification *)noti
{
    NSLog(@"notificationTestOne");
}

我們看輸出

2017-07-17 16:18:57.708 JJNotification[17071:1508348] notificationTestOne

可見锦亦,可以收到通知。

第二種監(jiān)聽通知

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(processTestTwo:) name:@"notificationTestTwo" object:nil];

- (void)processTestTwo:(NSNotification *)noti
{
    NSLog(@"notificationTestTwo");
}

下面看輸出

2017-07-17 16:24:20.773 JJNotification[17096:1537087] notificationTestTwo

可見令境,可以收到通知杠园。

第三種監(jiān)聽通知

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(processTestThree:) name:@"notificationTestThree" object:nil];
- (void)processTestThree:(NSNotification *)noti
{
    NSDictionary *notiDict = noti.userInfo;
    NSString *content = [notiDict objectForKey:@"key"];
    NSLog(@"notificationTestThree = %@",content);
}

下面看輸出

2017-07-17 16:24:20.773 JJNotification[17096:1537087] notificationTestThree = content

可見,還是可以監(jiān)聽到通知舔庶。


通知的移除

不用的監(jiān)聽通知要移除抛蚁,移除通知一般都是在delloc中完成,在delloc中可以移除全部監(jiān)聽的通知惕橙,還可以移除指定名字的通知瞧甩。

移除全部通知


- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

如果這么寫,那么上面三個notificationTestOne弥鹦、notificationTestTwo亲配、notificationTestThree通知都會被移除,可謂一勞永逸惶凝。

移除指定名字的通知

但是有的時候的需求是只要移除指定的某個通知吼虎,而保留某一個或者幾個通知,具體如下所示:

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"notificationTestOne" object:nil];
}

這樣子就把名字為notificationTestOne的通知移除了苍鲜,其他的通知還會起作用思灰,保留著監(jiān)聽的功能。

后記

這里寫的就是ios API以及通知的監(jiān)聽混滔、發(fā)送以及移除等基本知識洒疚,目的就是給新手能看明白,后面的幾篇我會加入稍微難一點的東西還有就是一些通知過程中碰到的坑坯屿。

風(fēng)景
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末油湖,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子领跛,更是在濱河造成了極大的恐慌乏德,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,000評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吠昭,死亡現(xiàn)場離奇詭異喊括,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)矢棚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評論 3 399
  • 文/潘曉璐 我一進(jìn)店門郑什,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蒲肋,你說我怎么就攤上這事蘑拯《勐” “怎么了?”我有些...
    開封第一講書人閱讀 168,561評論 0 360
  • 文/不壞的土叔 我叫張陵申窘,是天一觀的道長弯蚜。 經(jīng)常有香客問我,道長偶洋,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,782評論 1 298
  • 正文 為了忘掉前任距糖,我火速辦了婚禮玄窝,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘悍引。我一直安慰自己恩脂,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,798評論 6 397
  • 文/花漫 我一把揭開白布趣斤。 她就那樣靜靜地躺著俩块,像睡著了一般。 火紅的嫁衣襯著肌膚如雪浓领。 梳的紋絲不亂的頭發(fā)上玉凯,一...
    開封第一講書人閱讀 52,394評論 1 310
  • 那天,我揣著相機(jī)與錄音联贩,去河邊找鬼漫仆。 笑死,一個胖子當(dāng)著我的面吹牛泪幌,可吹牛的內(nèi)容都是我干的盲厌。 我是一名探鬼主播,決...
    沈念sama閱讀 40,952評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼祸泪,長吁一口氣:“原來是場噩夢啊……” “哼吗浩!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起没隘,我...
    開封第一講書人閱讀 39,852評論 0 276
  • 序言:老撾萬榮一對情侶失蹤懂扼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后右蒲,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體微王,經(jīng)...
    沈念sama閱讀 46,409評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,483評論 3 341
  • 正文 我和宋清朗相戀三年品嚣,在試婚紗的時候發(fā)現(xiàn)自己被綠了炕倘。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,615評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡翰撑,死狀恐怖罩旋,靈堂內(nèi)的尸體忽然破棺而出啊央,到底是詐尸還是另有隱情,我是刑警寧澤涨醋,帶...
    沈念sama閱讀 36,303評論 5 350
  • 正文 年R本政府宣布瓜饥,位于F島的核電站,受9級特大地震影響浴骂,放射性物質(zhì)發(fā)生泄漏乓土。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,979評論 3 334
  • 文/蒙蒙 一溯警、第九天 我趴在偏房一處隱蔽的房頂上張望趣苏。 院中可真熱鬧,春花似錦梯轻、人聲如沸食磕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽彬伦。三九已至,卻和暖如春伊诵,著一層夾襖步出監(jiān)牢的瞬間单绑,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評論 1 272
  • 我被黑心中介騙來泰國打工曹宴, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留询张,地道東北人。 一個月前我還...
    沈念sama閱讀 49,041評論 3 377
  • 正文 我出身青樓浙炼,卻偏偏與公主長得像份氧,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子弯屈,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,630評論 2 359

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

  • 概述 在多數(shù)移動應(yīng)用中任何時候都只能有一個應(yīng)用程序處于活躍狀態(tài)蜗帜,如果其他應(yīng)用此刻發(fā)生了一些用戶感興趣的那么通過通知...
    莫離_焱閱讀 6,519評論 1 8
  • 點擊查看原文 Web SDK 開發(fā)手冊 SDK 概述 網(wǎng)易云信 SDK 為 Web 應(yīng)用提供一個完善的 IM 系統(tǒng)...
    layjoy閱讀 13,786評論 0 15
  • 轉(zhuǎn)載自南峰子的技術(shù)博客 一個NSNotificationCenter對象(通知中心)提供了在程序中廣播消息的機(jī)制,...
    我消失1314閱讀 899評論 0 2
  • NSNotificationCenter對象(通知中心)提供了在程序中廣播消息的機(jī)制资厉,它實質(zhì)上就是一個通知分發(fā)表厅缺。...
    9de75b652cd9閱讀 756評論 0 1
  • 一個NSNotificationCenter對象(通知中心)提供了在程序中廣播消息測機(jī)制,它實質(zhì)上就是一個通知分發(fā)...
    DomAndMona閱讀 809評論 0 2