你真的瞭解NSNotificationCenter嗎?,nsnotificationcenter

來源:互聯網
上載者:User

你真的瞭解NSNotificationCenter嗎?,nsnotificationcenter

一:首先查看一下關於NSNotificationCenter的定義

@interface NSNotificationCenter : NSObject {    @package    void * __strong _impl;    void * __strong _callback;    void *_pad[11];}//單例獲得訊息中心對象+ (NSNotificationCenter *)defaultCenter;//增加訊息監聽 第一個參數是觀察者為本身,第二個參數表示訊息回調的方法,第三個訊息通知的名字,第四個為nil表示表示接受所有寄件者的訊息- (void)addObserver:(id)observer selector:(SEL)aSelector name:(nullable NSString *)aName object:(nullable id)anObject;//發送通知 三種方式- (void)postNotification:(NSNotification *)notification;- (void)postNotificationName:(NSString *)aName object:(nullable id)anObject;- (void)postNotificationName:(NSString *)aName object:(nullable id)anObject userInfo:(nullable NSDictionary *)aUserInfo;//移除監聽- (void)removeObserver:(id)observer;//移除監聽特定訊息- (void)removeObserver:(id)observer name:(nullable NSString *)aName object:(nullable id)anObject;//增加監聽 又提供了一個以block方式實現的添加觀察者的方法- (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

每一個程式都有一個自己的通知中樞,即NSNotificationCenter對象。NSNotificationCenter這個也是我們平常用到的相關訊息內容操作;NSNotificationCenter是一個單列,我們可以通過defaultCenter來擷取到通知中樞這個單列;通知中樞實際上是iOS程式內部之間的一種訊息廣播機制,主要為瞭解決應用程式內部不同對象之間解耦而設計。它是基於觀察者模式設計的,不能跨應用程式進程通訊,當通知中樞接收到訊息之後會根據內部的訊息轉寄表,將訊息發送給訂閱者;

知識點1:訊息的運用步驟

1:建立通知並發送

        NSNotification *notification =[NSNotification notificationWithName:@"qjwallet" object:nil userInfo:nil];        //通過通知中樞發送通知        [[NSNotificationCenter defaultCenter] postNotification:notification];

2:在接收的頁面註冊訊息通知

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

3:處理接收到的內容,並進行操作

- (void)qjwalletNotification:(NSNotification *)text{    //NSLog(@"%@",text.userInfo[@"orderid"]);    NSLog(@"-----接收到通知------");}

4:移除訊息通知

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

知識點2:關於建立通知並發送另外兩個方法

方法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];

上面兩個方法已經把NSNotification對象封裝一層,所以只要傳入相關的對象屬性就可以;

知識點3:通過NSNotificationCenter註冊通知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(@"名稱:%@----對象:%@",name,object);}-(void)notificationSecond:(NSNotification *)notification{    NSString  *name=[notification name];    NSString  *object=[notification object];    NSDictionary  *dict=[notification userInfo];    NSLog(@"名稱:%@----對象:%@",name,object);    NSLog(@"擷取的值:%@",[dict objectForKey:@"key"]);}

知識點4:移除通知訊息

-(void)dealloc{    NSLog(@"觀察者銷毀了");    [[NSNotificationCenter defaultCenter] removeObserver:self];}也可以針對某一個進行移除:[[NSNotificationCenter defaultCenter] removeObserver:self name:@"First" object:nil];

知識點5:如果notificationName為nil,則會接收所有的通知(如果notificationSender不為空白,則接收所有來自於notificationSender的所有通知)。如代碼清單1所示。如果notificationSender為nil,則會接收所有notificationName定義的通知;否則,接收由notificationSender發送的通知。監聽同一條通知的多個觀察者,在通知到達時,它們執行回調的順序是不確定的,所以我們不能去假設操作的執行會按照添加觀察者的順序來執行

知識點6:addObserverForName監聽訊息處理跟addObserver的差別

在前面addObserver有介紹它的四個參數作用,分別指定了通知的觀察者、處理通知的回調、通知名及通知的發送對象;而addObserverForName同樣是監聽訊息處理,只是它並沒有觀察者,卻多出一個隊列跟一個block的處理;addObserverForName參數說明,name和obj為nil時的情形與前面一個方法addObserver是相同的。如果queue為nil,則訊息是預設在post線程中同步處理,即通知的post與轉寄是在同一線程中;但如果我們指定了操作隊列,情況就變得有點意思了,我們一會再講。block塊會被通知中樞拷貝一份(執行copy操作),以在堆中維護一個block對象,直到觀察者被從通知中樞中移除。所以,應該特別注意在block中使用外部對象,避免出現對象的循環參考。如果一個給定的通知觸發了多個觀察者的block操作,則這些操作會在各自的Operation Queue中被並發執行。所以我們不能去假設操作的執行會按照添加觀察者的順序來執行。該方法會返回一個表示觀察者的對象,記得在不用時釋放這個對象。

執行個體在指定隊列中接收通知:

@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

在這裡,我們在主線程裡添加了一個觀察者,並指定在主線程隊列中去接收處理這個通知。然後我們在一個全域隊列中post了一個通知。我們來看下輸出結果:

post thread = <NSThread: 0x7ffe0351f5f0>{number = 2, name = (null)}receive thread = <NSThread: 0x7ffe03508b30>{number = 1, name = main}

可以看到,訊息的post與接收處理並不是在同一個線程中。如上面所提到的,如果queue為nil,則訊息是預設在post線程中同步處理;

二:關於NSNotification的定義

@interface NSNotification : NSObject <NSCopying, NSCoding>//這個成員變數是這個訊息對象的唯一標識,用於辨別訊息對象@property (readonly, copy) NSString *name;// 這個成員變數定義一個對象,可以理解為針對某一個對象的訊息,代表通知的寄件者@property (nullable, readonly, retain) id object;//這個成員變數是一個字典,可以用其來進行傳值@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;@end

NSNotification顧名思義就是通知的作用,一個對象通知另外一個對象,可以用來傳遞參數、通訊等作用,與delegate的一對一不同,通知是一對多的。在一個對象中註冊了通知,那麼其他任意對象都可以來對這個對象發出通知。因為屬性都是唯讀,如果要建立訊息時要用下面NSNotification (NSNotificationCreation)分類相應的方法進行初始化;

三: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對象,用於訊息的發送對象;

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.