IOS中的通知(NSNotifcation)

前言

通知中心是一個單例。通知在iOS中是一種設計模式。每一個應用程序都有一個通知中心NSNotificationCenter實例, 專門負責協助不同對象之間的消息通信.

任何一個對象都可以向通知中心發佈NSNotification, 描述自己在做什麼,而任何註冊了該通知的對象該特定通知發佈的時候會收到這個通知。

獲取通知中心對象

通過下面的方式來獲取通知中心對象:

NSNotificationCenter *center = [NSNotificationCenter  defaultCenter];

通知對象主要屬性

一個完整通知,也就是NSNotification對象,有下面這三個主要的屬性:

@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;
 
+ (instancetype)notificationWithName:(NSString *)aName 
                              object:(nullable id)anObject;
+ (instancetype)notificationWithName:(NSString *)aName 
                              object:(nullable id)anObject 
                            userInfo:(nullable NSDictionary *)aUserInfo;

蘋果還提供了一個初始化方法,但是蘋果要求不能使用:

/* do not invoke; not a valid initializer for this class */
- (instancetype)init /*NS_UNAVAILABLE*/;

發佈通知

通知的發佈,需要通過通知中心NSNotificationCenter來發布。發佈通知中幾個三個方法:

- (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)addObserver:(id)observer
           selector:(SEL)aSelector 
           name:(nullable NSString *)aName
            object:(nullable id)anObject;
 
- (id <NSObject>)addObserverForName:(nullable NSString *)name 
                             object:(nullable id)obj
                              queue:(nullable NSOperationQueue *)queue 
                              usingBlock:(void (^)(NSNotification *note))block

第一個方法使用的方式是最多的,第二個方法很少見到使用。第二個方法是支持block回調的,而queue參數就是在哪個隊列。

取消註冊通知

通知註冊了,在不需要時還需要移除註冊。通知中心不會保留監聽器對象, 在通知中心註冊過的對象,必須在該對象釋放前取消註冊. 否則,當相應的通知再次出現時, 通知中心仍然會向該監聽器發送消息. 因爲, 相應的監聽器對象已經被釋放了, 所以可能會導致應用崩潰,這種崩潰很常見。

蘋果提供了兩個方法,可以移除註冊:

- (void)removeObserver:(id)observer;
 
- (void)removeObserver:(id)observer
                  name:(nullable NSString *)aName
                object:(nullable id)anObject;


通常,我們會在控制器的dealloc之前,先取消註冊通知:

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

如果我們只是想取消某一個通知的註冊,而不是全部,那麼可以使用第二個方法,將通知名稱傳過去,就會只取消註冊該通知。

鍵盤通知

對於鍵盤,我們經常需要註冊與移除註冊通知:

UIKeyboardWillShowNotification // 鍵盤即將顯示 
UIKeyboardDidShowNotification // 鍵盤顯示完畢 
UIKeyboardWillHideNotification // 鍵盤即將隱藏 
UIKeyboardDidHideNotification // 鍵盤隱藏完畢 
UIKeyboardWillChangeFrameNotification // 鍵盤的位置尺寸即將發生改變 
UIKeyboardDidChangeFrameNotification // 鍵盤的位置尺寸改變完畢



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章