NSNotificationCenter - 通知中心

是什么?

  • 可以理解為,它就是一個系統創建的平臺。
  • '通知發布者' 和 '通知接收者'之間溝通的橋梁。


什么特點?

  • 每一個應用程序,都有一個通知中心
  • 它是系統定義得,不需要手動創建。
  • 任何一個對象,都可以向通知中心,發布通知 (NSNotification)
    其他感興趣的對象 (Observer), 可以申請在某個通知發布時 / 某個特定對象發布通知時 ,收到這個通知

有什么用?

  • 負責協調多個對象之間消息的通信。
  • 發布通知, 注冊監聽器,銷毀監聽器。

怎么使用?

  • 通知中心(NSNotificationCenter) 是系統創建得,不需要自己手動創建,那么怎么獲取系統的NSNotificationCenter呢?
    • [NSNotificationCenter defaultCenter] 系統的通知中心
    • 發送到應用程序的所有系統通知都會發布到通知中心。您也可以在此處發布自己的通知。

注冊監聽器

  • - addObserver: selector: name: object:
    observer 監聽器,( 誰要接收這個通知)
    aSelector 收到通知后,回調監聽器的這個方法,并且把通知對象當做參數傳入。
    aName 通知名稱。如為nil,那么無論通知名稱叫什么,監聽者都能收到
    anObject 通知的發布者。如果anObject為nil且aName為nil,那么監聽者能收到所有通知。
    - (void)addObserver:(id)observer 
             selector:(SEL)aSelector 
                 name:(NSNotificationName)aName 
               object:(id)anObject;
    
  • - addObserverForName: object: queue: usingBlock:
    name 通知名稱
    obj 通知發布者
    queue 決定block在哪個操作隊列執行,如果為nil,默認在當前操作隊列中同步執行。
    block 收到通知時執行的塊。
    - (id<NSObject>)addObserverForName:(NSNotificationName)name 
                                object:(id)obj 
                                 queue:(NSOperationQueue *)queue 
                            usingBlock:(void (^)(NSNotification *note))block;
    
    • 示例代碼
      沒有'監聽者',系統就是監聽者。
      代碼含義: 無論誰發布了通知名稱為'jdNoteName'的通知,就會調用'block'里面的方法。
      [[NSNotificationCenter defaultCenter]addObserverForName:jdNoteName object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
          NSLog(@"%@發送的%@,消息內容是:%@",[note.object name],note.name,note.userInfo);
      }];
      [[NSNotificationCenter defaultCenter] postNotificationName:jdNoteName object:compAL userInfo:@{@"title":@"medical is a  problem"}];
      [[NSNotificationCenter defaultCenter] postNotificationName:jdNoteName object:compJD userInfo:@{@"title":@"JD come on"}];
      
      輸出結果:
      阿里巴巴發送的717消費券-通知,消息內容是:{
          title = "medical is a  problem";
      }
      京東發送的717消費券-通知,消息內容是:{
          title = "JD come on";
      }
      

發布通知

  • 參數含義:
    aName 通知名稱
    anObject 通知的發布者
    userInfo 額外信息(通知發布者傳遞給通知接收者[監聽者]的信息內容)
    notification 要發布的通知

  • - postNotification:
    將給定的通知發布到通知中心

    - (void)postNotification:(NSNotification *)notification
    
  • - postNotificationName: object:
    創建具有給定名稱和發件人的通知,并將其發布到通知中心

    - (void)postNotificationName:(NSNotificationName)aName 
                          object:(id)anObject
    
  • - postNotificationName: object: userInfo:
    創建具有給定名稱,發件人和信息的通知,并將其發布到通知中心

    - (void)postNotificationName:(NSNotificationName)aName 
                          object:(id)anObject 
                        userInfo:(NSDictionary *)aUserInfo
    
  • 示例代碼

     //注冊監聽器(監聽者:p1,監聽所有對象發布的所有通知,監聽到通知后,調用getMessage:方法)
     [[NSNotificationCenter defaultCenter] addObserver:p1 selector:@selector(getMessage:) name:nil object:nil];
     //創建 "通知",且將通知發送到 "通知中心"
     [[NSNotificationCenter defaultCenter] postNotificationName:alNoteTemp object:compAL];
     [[NSNotificationCenter defaultCenter] postNotificationName:alNoteTest object:compAL userInfo:@{@"你瞅啥":@"瞅你咋地"}];
    

銷毀監聽器
'通知中心'注冊過的對象(監聽者 / 監聽器),必須在該對象釋放前,取消注冊

  • 為什么要銷毀監聽器?
    如果,在'監聽者'釋放前,不在"通知中心"取消注冊,
    那么,當相應的'通知'再次發出時,'通知中心'會再次給'監聽者 / 監聽器'發送消息,
    但是,'監聽者' 已經釋放了,所以會產生野指針,導致系統崩潰!
    注: 現在版本已經升級,系統會自動銷毀'通知中心注冊的沒用的監聽者'
  • 怎么銷毀?
    • removeObserver: name: object:
      從通知中心的調度表中刪除匹配的條目
      observer 觀察者/監聽者
      aName 通知名稱
      anObject 通知發布者
      - (void)removeObserver:(id)observer 
                      name:(NSNotificationName)aName 
                    object:(id)anObject
      
        // "p1"不在監聽"comp1"發布的"軍事新聞"! 
       [[NSNotificationCenter defaultCenter] removeObserver: p1 name:@"軍事新聞" object: comp1 ] ;
      
    • - removeObserver:
      從通知中心的分發表中刪除所有指定觀察者的條目
      - (void)removeObserver:(id)observer
      // p1 不在監聽任何通知
      [[NSNotificationCenter defaultCenter] removeObserver: p1 ];
  • 什么時候銷毀?
    對象銷毀前,會調用dealloc方法

  • 通知和代理的選擇
    • 代理: 1個對象只能告訴,另外1個對象發生了什么事。
    • 通知: 1個對象能告訴N個對象發生了什么事。
      ????1個對象能知道N個對象發生了什么事。
    • 通知比較簡單,但是容易出錯。
      如, "通知名"拼寫錯誤,在編譯時不會有任何提示,運行時才會報錯。
    • 代理比較規范,但有些麻煩。
    • 代理和通知都能完成,對象和對象之間的通信!
      但是能用"代理"就不用"通知"

也可以看看

NSNotification - 通知
模擬通知


來自于哪里?

  • iOS-MJ-UI基礎-大神班/day-11/05-模擬通知
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。