iOS NSNotificationCenter詳解

通知中心的特色:多線程

1:同步執行app

2: 一對多發送消息異步

3: 下降程序耦合度post

通知中心是單例,目的就是從任意一個發送消息到任意一個接收者,是同步執行的。this

那麼什麼是同步呢?atom

用網上經典的說法,就是我叫朋友去吃飯,若是他沒來,我就繼續叫,等到他出來了咱們才一塊兒去吃,這就是同步;若是我叫朋友去吃飯,叫完不管他有沒有來,我都先去吃飯,spa

這就是異步;在通知中內心就是每發送一次消息,要等消息被接收並徹底執行完裏面的方法,而後才返回來發送第二條消息,這就是同步,即通知中心發送消息是一條一條發送,並且是上條消息執行完才執行下一條的。線程

 

NSNotificationCenter的使用:
步驟主要有三個:註冊通知、發送廣播、銷燬廣播   另外還有建立通知code

默認都是用defaultCenter,而通知不須要時可省略server

先介紹一下聲明方法:

 

建立一個通知的方法:

第一種方法三個參數:name:通知名稱   object:標識(nullable id類型)  userInfo:字典類型,傳值用

object這個參數要注意一下,其實這個參數不是用來傳值的,若是要傳值,就用userInfo,而object的做用是用來指定收發對象的,即接收端過濾廣播用的,不使用時用nil

NSDictionary *dic = [[NSDictionary alloc]initWithObjectsAndKeys:@"cen",@"ter", nil];

[NSNotification notificationWithName:@"center" object:@"center2" userInfo:dic];

第二種兩個參數,object不是傳值用,同上

[NSNotification notificationWithName:@"center" object:nil];//不帶標識
//對比:
[NSNotification notificationWithName:@"center" object:@"center1"];//帶標識

 

添加觀察者,註冊通知

第一種方法 參數1:發生通知的對象;參數2:方法;參數3:通知的名稱;參數4:標示(同前)

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

第二種方法 參數1:通知名稱,參數2:標識,參數3:隊列,參數4:block[跟方法1的區別是使用了block和隊列]

[[NSNotificationCenter defaultCenter]addObserverForName:@"ocenter" object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
      
    }];

 

發送廣播

第一種 參數類型是notification  直接把通知對象發送出去

[[NSNotificationCenter defaultCenter]postNotification:self.notification];

第二種 參數跟之前的同樣

[[NSNotificationCenter defaultCenter]postNotificationName:@"center" object:nil userInfo:dic];

第三種

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

 

銷燬廣播

第一種 經過廣播名字來銷燬廣播

[[NSNotificationCenter defaultCenter]removeObserver:self name:@"center" object:nil];

第二種 經過廣播對象銷燬廣播  這裏注意若是不使用詳細的對象來銷燬的話,那儘可能避免使用這個方法來銷燬廣播,假如self是控制器,那可能連繫統本身註冊的

其它通知也被一塊兒銷燬了,除非連同系統那部分也都不要了,就可用self

[[NSNotificationCenter defaultCenter]removeObserver:self.notification];

 

舉個例子:

第一步:建立通知

聲明方式

@property(nonatomic,strong)NSNotification *notification;

NSDictionary *dic = [[NSDictionary alloc]initWithObjectsAndKeys:@"cen",@"ter", nil];

self.cnotification = [NSNotification notificationWithName:@"center" object:@"user" userInfo:dic];

 

第二步:註冊通知

接收方的控制器裏 監聽name爲center的通知,可在多個控制器裏註冊通知,而通知中心不用知道接收方是什麼,接收方也可接收,這就能夠下降程序的耦合度

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

這裏就用到object的過濾效果,假如上面建立了多個通知名字都爲center,那麼在接收的時候就能夠用object過濾

-(void)tion:(NSNotification *)notification{

    if ([notification.object isEqualToString:@"user"]) {
        NSLog(@"this's notification is center");
    }
}

 

第三步:發送廣播

作個循環發送的廣播

這裏用從建立通知的地方用定時器發送通知

[NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(post) userInfo:nil repeats:YES];
-(void)post
{
       [[NSNotificationCenter defaultCenter]postNotification:self.notification];
}

若是建立多個post發送廣播的話,可添加對應的方法來驗證通知中心的一對多和通知中心的同步性,通知中心每發送一個廣播以後會等待註冊通知裏的方法(如例子裏的tion方法)執行完纔會發送下一條廣播,不管該方法的執行時間有多長,在沒有引入多線程的時候,按發送的廣播前後順序執行,先發送的先執行,跟註冊通知的建立前後順序沒有關

系,固然接收端必須已經實例化才能接收;若是引入了多線程發送消息,那就得看線程裏誰先被髮送了,固然也是先發送的先執行,

 

第四步:最後是銷燬,例如

[[NSNotificationCenter defaultCenter]removeObserver:self name:@"center" object:nil];

 簡化使用時,可用二、三、4步便可,例子就須要修改,能夠根據須要從註冊裏添加object,和發送的通知裏帶信息

 

這裏還涉及到觀察者的註冊和銷燬問題

觀察者的建立和銷燬要成對存在,一次添加對應一次銷燬

建立的位置如   viewWillAppear  和  viewDidAppear, 銷燬的位置如   viewWillDisappear 、viewDidDisappear  和 dealloc

就是在頁面出現的時候註冊通知,頁面消失時移除通知。必定要成雙成對出現,若是你只在viewWillAppear 中 addObserver沒有在viewWillDisappear 中 removeObserver那麼當消息發生的時候,你的方法會被調用屢次。

 

固然詳細的仍是根據須要的來進行修改,若有些通知是在整個工程裏用到,建立在appDelegate裏,若是通知中心在其餘地方有須要用到而不用立刻銷燬時,使用完成時再進行

銷燬,從實際狀況肯定。

NSNotificationCenter就到這了,若是有地方說得不對的話,歡迎你們指出

相關文章
相關標籤/搜索