iOS中通知中心NSNotificationCenter應用總結


通知中心(NSNotificationCenter)實際是在程序內部提供了一種廣播機制。把接收到的消息,根據內部的消息轉發表,將消息轉發給需要的對象。這句話其實已經很明顯的告訴我們要如何使用通知了。第一步:在需要的地方注冊要觀察的通知,第二步:在某地方發送通知。(這里注意:發送的通知可能是我們自定義的,也可能是系統的)。

一,使用通知

第1中創建通知方法

//注意,通知的使用是有先后順序的

//一定要先監聽通知,然后在發送通知

 //第一種方法
    // 添加一個通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(addNotification) name:@"tongzhi" object:nil];
    
    //發送一個通知
    [[NSNotificationCenter defaultCenter] postNotificationName:@"tongzhi" object:nil];
  //發送通知也可以傳遞一些參數
    [NSNotificationCenter defaultCenter] postNotificationName:<#(nonnull NSNotificationName)#> object:<#(nullable id)#> userInfo:<#(nullable NSDictionary *)#>

 

可以在監聽的通知的方法獲取通知的信息

- (void)addNotification {

    NSLog(@"接受通知");
}

最后要移除通知

- (void)dealloc {

    //移除觀察者 self
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

 

第2種通知的使用使用 block 比較方便簡單

這個方法需要一個id類型的值接受

@property (nonatomic, weak) id observe;

 

    //第二種方法
    //Name: 通知的名稱
    //object:誰發出的通知
    //queue: 隊列,決定 block 在哪個線程中執行, nil  在發布通知的線程中執行
    //usingBlock: 只要監聽到通知,就會執行這個 block
    //這個通知返回一個 id 這個通知同樣需要移除
   _observe = [[NSNotificationCenter defaultCenter] addObserverForName:@"tongzhi" object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
        NSLog(@"收到了通知");
    }];

    [[NSNotificationCenter defaultCenter] postNotificationName:@"tongzhi" object:nil];
    

同樣,這里也需要移除通知,但是這里的觀察者不是 self 而是 _observe

- (void)dealloc {

    //移除觀察者 _observe
    [[NSNotificationCenter defaultCenter] removeObserver:_observe];
}

 

二 .通知在多線程中的使用

通知在多線程中使用

//通知在接收的方法跟發送通知所在的線程中一樣

異步發送通知, 主線程監聽通知, 接收通知的方法在子線程中

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {

    //發送通知
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [[NSNotificationCenter defaultCenter] postNotificationName:@"tongzhi" object:nil];
    });
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //多線程中使用通知
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(addNotification) name:@"tongzhi" object:nil];
    
}

- (void)addNotification {
    NSLog(@"接受通知");
    NSLog(@"%@",[NSThread currentThread]);
    
    //主線程:監聽通知,異步發送通知
    //總結: 接受通知的代碼由發出通知的線程
    //更新 UI
    dispatch_sync(dispatch_get_main_queue(), ^{
        //更新 UI
    });
}

控制台輸出 : 異步

2016-10-07 15:17:05.537 通知多線程使用[5798:299202] 接受通知
2016-10-07 15:17:05.538 通知多線程使用[5798:299202] <NSThread: 0x60800026d8c0>{number = 4, name = (null)}

主線程中發送通知,異步線程中監聽通知

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {


    
    //主線程中發送通知
     [[NSNotificationCenter defaultCenter] postNotificationName:@"tongzhi" object:nil];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //多線程中使用通知

    
    //異步監聽通知
    
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(addNotification) name:@"tongzhi" object:nil];
    });
}

- (void)addNotification {
    NSLog(@"接受通知");
    NSLog(@"%@",[NSThread currentThread]);
    
    //異步:監聽通知,主線程發送通知
    //總結: 接受通知的代碼由發出通知的線程

}

控制台輸出

2016-10-07 15:28:40.160 通知多線程使用[5879:321079] 接受通知
2016-10-07 15:28:40.160 通知多線程使用[5879:321079] <NSThread: 0x600000072ac0>{number = 1, name = main}

使用 block 創建通知的方法,

queue :[NSOperationQueue mainQueue] 這樣都會在主線程中執行block 中代碼
    _observe = [[NSNotificationCenter defaultCenter] addObserverForName:@"tongzhi" object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
        NSLog(@"收到了通知");
    }];

控制台輸出 : 主線程中執行

2016-10-07 15:36:39.277 通知多線程使用[5979:332663] 收到了通知
2016-10-07 15:36:39.277 通知多線程使用[5979:332663] <NSThread: 0x60000006ea40>{number = 1, name = main}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM