通知中心(NSNotificationCenter)
- 每一個(gè)應(yīng)用程序都有一個(gè)通知中心(NSNotificationCenter)實(shí)例,專門負(fù)責(zé)協(xié)助不同對象之間的消息通信
- 任何一個(gè)對象都可以向通知中心發(fā)布通知(NSNotification),描述自己在做什么。其他感興趣的對象(Observer)可以申請?jiān)谀硞€(gè)特定通知發(fā)布時(shí)(或在某個(gè)特定的對象發(fā)布通知時(shí))收到這個(gè)通知
- 通知中心是同步廣播
- 如果我們需要異步的處理消息,則應(yīng)該使用通知隊(duì)列NSNotificationQueue 在多線程程序中,通知會(huì)被分發(fā)到每一個(gè)發(fā)起消息的線程中,這可能與觀察者注冊時(shí)所在的線程已經(jīng)不是同一個(gè)線程。
通知(NSNotification)
- 一個(gè)完整的通知一般包含三個(gè)屬性
- (NSString*)name; // 通知的名稱
- (id)object; // 通知發(fā)布者(是誰要發(fā)布通知)
- (NSDictionary*)userInfo; // 一些額外的信息(通知發(fā)布者傳遞給通知接收者的信息內(nèi)容)
- 初始化一個(gè)通知(NSNotification)對象
+ (instancetype)notificationWithName:(NSString*)aName object:(id)anObject;
+ (instancetype)notificationWithName:(NSString*)aName object:(id)anObject userInfo:(NSDictionary*)aUserInfo;
- (instancetype)initWithName:(NSString*)name object:(id)object userInfo:(NSDictionary*)userInfo;
- 發(fā)布通知
- (void)postNotification:(NSNotification*)notification;
//發(fā)布一個(gè)notification通知,可在notification對象中設(shè)置通知的名稱、通知發(fā)布者、額外信息等
- (void)postNotificationName:(NSString *)aName object:(id)anObject;
//發(fā)布一個(gè)名稱為aName的通知,anObject為這個(gè)通知的發(fā)布者
- (void)postNotificationName:(NSString *)aName object:(id)anObject userInfo:(NSDictionary *)aUserInfo;
//發(fā)布一個(gè)名稱為aName的通知,anObject為這個(gè)通知的發(fā)布者,aUserInfo為額外信息
監(jiān)聽通知
注冊通知監(jiān)聽器(接受通知)
- (void)addObserver:(id)observer selector:(SEL)aSelector name:(NSString*)aName object:(id)anObject;
observer:監(jiān)聽器,即誰要接收這個(gè)通知
aSelector:收到通知后,回調(diào)監(jiān)聽器的這個(gè)方法,并且把通知對象當(dāng)做參數(shù)傳入
aName:通知的名稱。如果為nil,那么無論通知的名稱是什么,監(jiān)聽器都能收到這個(gè)通知
anObject:通知發(fā)布者。如果為anObject和aName都為nil,監(jiān)聽器都收到所有的通知
- (id)addObserverForName:(NSString *)name object:(id)obj queue:(NSOperationQueue*)queue usingBlock:(void(^)(NSNotification*note))block;
name:通知的名稱
obj:通知發(fā)布者
block:收到對應(yīng)的通知時(shí),會(huì)回調(diào)這個(gè)block
queue:決定了block在哪個(gè)操作隊(duì)列中執(zhí)行,如果傳nil,默認(rèn)在當(dāng)前操作隊(duì)列中同步執(zhí)行
- 取消注冊通知監(jiān)聽器
通知中心不會(huì)保留(retain)監(jiān)聽器對象,在通知中心注冊過的對象,必須在該對象釋放前取消注冊。否則,當(dāng)相應(yīng)的通知再次出現(xiàn)時(shí),通知中心仍然會(huì)向該監(jiān)聽器發(fā)送消息。因?yàn)橄鄳?yīng)的監(jiān)聽器對象已經(jīng)被釋放了,所以可能會(huì)導(dǎo)致應(yīng)用崩潰
- (void)removeObserver:(id)observer;
- (void)removeObserver:(id)observer name:(NSString *)aName object:(id)anObject;
一般在監(jiān)聽器銷毀之前取消注冊(如在監(jiān)聽器中加入下列代碼):
- (void)dealloc {
//[super dealloc]; 非ARC中需要調(diào)用此句
[[NSNotificationCenter defaultCenter] removeObserver:self];
}