你真的了解NSNotificationCenter吗?
一:首先查看一下關(guān)于NSNotificationCenter的定義
@interface NSNotificationCenter : NSObject {@packagevoid * __strong _impl;void * __strong _callback;void *_pad[11]; }//單例獲得消息中心對(duì)象 + (NSNotificationCenter *)defaultCenter;//增加消息監(jiān)聽(tīng) 第一個(gè)參數(shù)是觀察者為本身,第二個(gè)參數(shù)表示消息回調(diào)的方法,第三個(gè)消息通知的名字,第四個(gè)為nil表示表示接受所有發(fā)送者的消息 - (void)addObserver:(id)observer selector:(SEL)aSelector name:(nullable NSString *)aName object:(nullable id)anObject;//發(fā)送通知 三種方式 - (void)postNotification:(NSNotification *)notification; - (void)postNotificationName:(NSString *)aName object:(nullable id)anObject; - (void)postNotificationName:(NSString *)aName object:(nullable id)anObject userInfo:(nullable NSDictionary *)aUserInfo;//移除監(jiān)聽(tīng) - (void)removeObserver:(id)observer; //移除監(jiān)聽(tīng)特定消息 - (void)removeObserver:(id)observer name:(nullable NSString *)aName object:(nullable id)anObject;//增加監(jiān)聽(tīng) 又提供了一個(gè)以block方式實(shí)現(xiàn)的添加觀察者的方法 - (id <NSObject>)addObserverForName:(nullable NSString *)name object:(nullable id)obj queue:(nullable NSOperationQueue *)queue usingBlock:(void (^)(NSNotification *note))block NS_AVAILABLE(10_6, 4_0);@end每一個(gè)程序都有一個(gè)自己的通知中心,即NSNotificationCenter對(duì)象。NSNotificationCenter這個(gè)也是我們平常用到的相關(guān)消息內(nèi)容操作;NSNotificationCenter是一個(gè)單列,我們可以通過(guò)defaultCenter來(lái)獲取到通知中心這個(gè)單列;通知中心實(shí)際上是iOS程序內(nèi)部之間的一種消息廣播機(jī)制,主要為了解決應(yīng)用程序內(nèi)部不同對(duì)象之間解耦而設(shè)計(jì)。它是基于觀察者模式設(shè)計(jì)的,不能跨應(yīng)用程序進(jìn)程通信,當(dāng)通知中心接收到消息之后會(huì)根據(jù)內(nèi)部的消息轉(zhuǎn)發(fā)表,將消息發(fā)送給訂閱者;
知識(shí)點(diǎn)1:消息的運(yùn)用步驟
1:創(chuàng)建通知并發(fā)送
NSNotification *notification =[NSNotification notificationWithName:@"qjwallet" object:nil userInfo:nil];//通過(guò)通知中心發(fā)送通知[[NSNotificationCenter defaultCenter] postNotification:notification];2:在接收的頁(yè)面注冊(cè)消息通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(qjwalletNotification:) name:@"qjwallet" object:nil];3:處理接收到的內(nèi)容,并進(jìn)行操作
- (void)qjwalletNotification:(NSNotification *)text{//NSLog(@"%@",text.userInfo[@"orderid"]);NSLog(@"-----接收到通知------"); }4:移除消息通知
-(void)dealloc {[[NSNotificationCenter defaultCenter]removeObserver:self name:@"qjwallet" object:nil]; }知識(shí)點(diǎn)2:關(guān)于創(chuàng)建通知并發(fā)送另外兩個(gè)方法
方法1:[[NSNotificationCenter defaultCenter] postNotificationName:@"First" object:@"博客園"]; 方法2: NSDictionary *dict=[[NSDictionary alloc]initWithObjects:@[@"keso"] forKeys:@[@"key"]]; [[NSNotificationCenter defaultCenter] postNotificationName:@"Second" object:@"http://www.cnblogs.com" userInfo:dict];上面兩個(gè)方法已經(jīng)把NSNotification對(duì)象封裝一層,所以只要傳入相關(guān)的對(duì)象屬性就可以;
知識(shí)點(diǎn)3:通過(guò)NSNotificationCenter注冊(cè)通知NSNotification,viewDidLoad中
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationFirst:) name:@"First" object:nil];[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationSecond:) name:@"Second" object:nil]; -(void)notificationFirst:(NSNotification *)notification{NSString *name=[notification name];NSString *object=[notification object];NSLog(@"名稱:%@----對(duì)象:%@",name,object); }-(void)notificationSecond:(NSNotification *)notification{NSString *name=[notification name];NSString *object=[notification object];NSDictionary *dict=[notification userInfo];NSLog(@"名稱:%@----對(duì)象:%@",name,object);NSLog(@"獲取的值:%@",[dict objectForKey:@"key"]); }知識(shí)點(diǎn)4:移除通知消息
-(void)dealloc{NSLog(@"觀察者銷毀了");[[NSNotificationCenter defaultCenter] removeObserver:self]; }也可以針對(duì)某一個(gè)進(jìn)行移除:[[NSNotificationCenter defaultCenter] removeObserver:self name:@"First" object:nil];知識(shí)點(diǎn)5:如果notificationName為nil,則會(huì)接收所有的通知(如果notificationSender不為空,則接收所有來(lái)自于notificationSender的所有通知)。如代碼清單1所示。如果notificationSender為nil,則會(huì)接收所有notificationName定義的通知;否則,接收由notificationSender發(fā)送的通知。監(jiān)聽(tīng)同一條通知的多個(gè)觀察者,在通知到達(dá)時(shí),它們執(zhí)行回調(diào)的順序是不確定的,所以我們不能去假設(shè)操作的執(zhí)行會(huì)按照添加觀察者的順序來(lái)執(zhí)行
知識(shí)點(diǎn)6:addObserverForName監(jiān)聽(tīng)消息處理跟addObserver的差別
在前面addObserver有介紹它的四個(gè)參數(shù)作用,分別指定了通知的觀察者、處理通知的回調(diào)、通知名及通知的發(fā)送對(duì)象;而addObserverForName同樣是監(jiān)聽(tīng)消息處理,只是它并沒(méi)有觀察者,卻多出一個(gè)隊(duì)列跟一個(gè)block的處理;addObserverForName參數(shù)說(shuō)明,name和obj為nil時(shí)的情形與前面一個(gè)方法addObserver是相同的。如果queue為nil,則消息是默認(rèn)在post線程中同步處理,即通知的post與轉(zhuǎn)發(fā)是在同一線程中;但如果我們指定了操作隊(duì)列,情況就變得有點(diǎn)意思了,我們一會(huì)再講。block塊會(huì)被通知中心拷貝一份(執(zhí)行copy操作),以在堆中維護(hù)一個(gè)block對(duì)象,直到觀察者被從通知中心中移除。所以,應(yīng)該特別注意在block中使用外部對(duì)象,避免出現(xiàn)對(duì)象的循環(huán)引用。如果一個(gè)給定的通知觸發(fā)了多個(gè)觀察者的block操作,則這些操作會(huì)在各自的Operation Queue中被并發(fā)執(zhí)行。所以我們不能去假設(shè)操作的執(zhí)行會(huì)按照添加觀察者的順序來(lái)執(zhí)行。該方法會(huì)返回一個(gè)表示觀察者的對(duì)象,記得在不用時(shí)釋放這個(gè)對(duì)象。
實(shí)例在指定隊(duì)列中接收通知:
@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];[[NSNotificationCenter defaultCenter] addObserverForName:TEST_NOTIFICATION object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {NSLog(@"receive thread = %@", [NSThread currentThread]);}];dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{NSLog(@"post thread = %@", [NSThread currentThread]);[[NSNotificationCenter defaultCenter] postNotificationName:TEST_NOTIFICATION object:nil];}); }@end在這里,我們?cè)谥骶€程里添加了一個(gè)觀察者,并指定在主線程隊(duì)列中去接收處理這個(gè)通知。然后我們?cè)谝粋€(gè)全局隊(duì)列中post了一個(gè)通知。我們來(lái)看下輸出結(jié)果:
post thread = <NSThread: 0x7ffe0351f5f0>{number = 2, name = (null)} receive thread = <NSThread: 0x7ffe03508b30>{number = 1, name = main}可以看到,消息的post與接收處理并不是在同一個(gè)線程中。如上面所提到的,如果queue為nil,則消息是默認(rèn)在post線程中同步處理;
二:關(guān)于NSNotification的定義
@interface NSNotification : NSObject <NSCopying, NSCoding> //這個(gè)成員變量是這個(gè)消息對(duì)象的唯一標(biāo)識(shí),用于辨別消息對(duì)象 @property (readonly, copy) NSString *name; // 這個(gè)成員變量定義一個(gè)對(duì)象,可以理解為針對(duì)某一個(gè)對(duì)象的消息,代表通知的發(fā)送者 @property (nullable, readonly, retain) id object; //這個(gè)成員變量是一個(gè)字典,可以用其來(lái)進(jìn)行傳值 @property (nullable, readonly, copy) NSDictionary *userInfo;// 初始化方法 - (instancetype)initWithName:(NSString *)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;@endNSNotification顧名思義就是通知的作用,一個(gè)對(duì)象通知另外一個(gè)對(duì)象,可以用來(lái)傳遞參數(shù)、通信等作用,與delegate的一對(duì)一不同,通知是一對(duì)多的。在一個(gè)對(duì)象中注冊(cè)了通知,那么其他任意對(duì)象都可以來(lái)對(duì)這個(gè)對(duì)象發(fā)出通知。因?yàn)閷傩远际侵蛔x的,如果要?jiǎng)?chuàng)建消息時(shí)要用下面NSNotification (NSNotificationCreation)分類相應(yīng)的方法進(jìn)行初始化;
三:NSNotification (NSNotificationCreation)分類
@interface NSNotification (NSNotificationCreation)+ (instancetype)notificationWithName:(NSString *)aName object:(nullable id)anObject; + (instancetype)notificationWithName:(NSString *)aName object:(nullable id)anObject userInfo:(nullable NSDictionary *)aUserInfo;- (instancetype)init /*NS_UNAVAILABLE*/; /* do not invoke; not a valid initializer for this class */@end上面為初使化NSNotification對(duì)象,用于消息的發(fā)送對(duì)象;
?
?
?
最近有個(gè)妹子弄的一個(gè)關(guān)于擴(kuò)大眼界跟內(nèi)含的訂閱號(hào),每天都會(huì)更新一些深度內(nèi)容,在這里如果你感興趣也可以關(guān)注一下(嘿對(duì)美女跟知識(shí)感興趣),當(dāng)然可以關(guān)注后輸入:github 會(huì)有我的微信號(hào),如果有問(wèn)題你也可以在那找到我;當(dāng)然不感興趣無(wú)視此信息;
轉(zhuǎn)載于:https://www.cnblogs.com/wujy/p/5825690.html
總結(jié)
以上是生活随笔為你收集整理的你真的了解NSNotificationCenter吗?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: JSP中内置对象pageContent的
- 下一篇: HDU1402 A * B Proble