iOS--NSNotificationCenter多次接收問題的總結

??通知中心(NSNotificationCenter)是在程序內部提供了一種廣播機制,可以一對多的發送通知,通知的使用步驟:創建通知、發送通知、移除通知,創建通知有兩種方法,分別為[NSNotificationCenter defaultCenter] addObserver[NSNotificationCenter defaultCenter] addObserverForName:,首先介紹下第一種方法:

??一般最好在viewDidLoad的方法中創建通知,因為該方法只走一次,防止多次創建

??1、創建通知

- (void)viewDidLoad {
     [super viewDidLoad];
     //創建通知
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(respond:) name:@"tongzhi" object:nil];
}

//實現響應
- (void)respond:(NSNotification *)notification{
    //通知內容
    NSDictionary *dic = notification.object;    
}

??2、發送通知

 //發送通知
[[NSNotificationCenter defaultCenter] postNotificationName:@"tongzhi" object:nil];

??當然你可以傳遞一些自己封裝的數據,通過object就行,如:

NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:@"松",@"name",@"男",@"sex", nil];
 //發送通知
 [[NSNotificationCenter defaultCenter] postNotificationName:@"tongzhi" object:dic];

??3、移除通知

??移除通知一般在dealloc中實現,因為越來越多應用支持手勢返回,滑回一半又返回等操作,在頁面真正銷毀的時候移除最好

??移除有兩種方法,一個是移除當前頁面所有的通知,還有一種移除指定的通知,具體用哪個看實際情況,如下:

-(void)dealloc{
     // 移除當前所有通知
    [[NSNotificationCenter defaultCenter] removeObserver:self];

    //移除名為tongzhi的那個通知
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"tongzhi" object:nil];
}

??注意:dealloc方法不走一般原因有三個:

1、ViewController中存在NSTimer ,計時器是否銷毀;
2、ViewController中有關的代理 ,要記住delegate的屬性應該是assign;
3、ViewController中有Block,Block里面是否有強引用;

?? 下面介紹第二種使用的通知方法:

??1、創建通知

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

@property (nonatomic, weak) id observe;

??再創建通知

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

??該方法有個block,要操作的步驟可以直接寫在block里面,代碼的可讀比第一種高,所以用的人更多

??2、發送通知

//與第一種發送通知一樣
[[NSNotificationCenter defaultCenter] postNotificationName:@"tongzhi" object:nil];

??3、移除通知

- (void)dealloc {
    //移除觀察者 _observe
    [[NSNotificationCenter defaultCenter] removeObserver:_observe];
}

??從移除的方法,應該知道了,為什么第二種創建通知方法時要有一個id類型的值接受,千萬不要用第一種的注銷方法,這也是我用錯了的原因,我創建的時候沒用一個值接收,直接這么寫:

 [[NSNotificationCenter defaultCenter] addObserverForName:@"tongzhi" object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
        NSLog(@"收到了通知");
    }];

??導致通知未移除而重復創建,執行方法一次比一次多,而移除的時候用

-(void)dealloc{
    //用第二種創建方法錯誤的移除
    //移除名為tongzhi的那個通知
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"tongzhi" object:nil];
}

??從而導致程序出問題,還有一點值得注意的是,銷毀應該是哪里創建哪里銷毀,不要在發送的控制器里執行銷毀??!

聲明: 轉載請注明出處http://www.lxweimin.com/p/ab52ee91cbb0

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。