通知中心

  • ** 通知機(jī)制(消息機(jī)制)是一個(gè)應(yīng)用程序級(jí)別的操作UIApplication
  • 通知中心實(shí)際上是iOS程序內(nèi)部之間的一種消息廣播機(jī)制茉贡,主要為了解決應(yīng)用程序內(nèi)部不同對(duì)象之間解耦而設(shè)計(jì)。它是基于觀察者模式設(shè)計(jì)的潮酒,不能跨應(yīng)用程序進(jìn)程通信坟冲,當(dāng)通知中心接收到消息之后會(huì)根據(jù)內(nèi)部的消息轉(zhuǎn)發(fā)表磨镶,將消息發(fā)送給訂閱者

通知機(jī)制 與 NSNotification 區(qū)別

  • NSNotification是抽象的健提,不可見(jiàn)的
  • 推送通知是可見(jiàn)的(能用肉眼看到)
  • 對(duì)于很多初學(xué)者往往會(huì)把iOS中的本地通知琳猫、推送通知和iOS通知中心的概念弄混。其實(shí)二者之間并沒(méi)有任何關(guān)系私痹,事實(shí)上它們都不屬于一個(gè)框架脐嫂,前者屬于UIKit框架统刮,后者屬于Foundation框架。
    下面是一個(gè)簡(jiǎn)單的通知中心流程示意圖:
屏幕快照 2016-03-27 下午2.06.52.png

了解通知中心需要熟悉NSNotificationCenter和NSNotification兩個(gè)類(lèi):

  • NSNotificationCenter:是通知系統(tǒng)的中心账千,用于注冊(cè)和發(fā)送通知侥蒙,下表列出常用的方法
屏幕快照 2016-03-27 下午2.13.03.png
  • NSNotification:代表通知內(nèi)容的載體,主要有三個(gè)屬性:name代表通知名稱(chēng)匀奏,object代表通知的發(fā)送者鞭衩,userInfo代表通知的附加信息。

  • 很多東西都是通過(guò)通知中心來(lái)進(jìn)行應(yīng)用中各個(gè)組件通信娃善。例如說(shuō)道應(yīng)用程序生命周期問(wèn)題论衍,當(dāng)應(yīng)用程序啟動(dòng)后、進(jìn)入后臺(tái)聚磺、進(jìn)入前臺(tái)坯台、獲得焦點(diǎn)、失去焦點(diǎn)瘫寝,窗口大小改變蜒蕾、隱藏等都會(huì)發(fā)送通知。這個(gè)通知可以通過(guò)前面NSNotificationCenter進(jìn)行訂閱即可接收對(duì)應(yīng)的消息焕阿,下面的示例演示如何添加監(jiān)聽(tīng)獲得UIApplication的進(jìn)入后臺(tái)和獲得焦點(diǎn)的通知:

//
//  LTYViewController.m
//  NotificationCenter
//

#import "LTYViewController.h"

@interface LTYViewController ()

@end

@implementation LTYViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self addObserverToNotificationCenter];
    
}

#pragma mark 添加監(jiān)聽(tīng)
-(void)addObserverToNotificationCenter{
    /*添加應(yīng)用程序進(jìn)入后臺(tái)監(jiān)聽(tīng)
     * observer:監(jiān)聽(tīng)者
     * selector:監(jiān)聽(tīng)方法(監(jiān)聽(tīng)者監(jiān)聽(tīng)到通知后執(zhí)行的方法)
     * name:監(jiān)聽(tīng)的通知名稱(chēng)(下面的UIApplicationDidEnterBackgroundNotification是一個(gè)常量)
     * object:通知的發(fā)送者(如果指定nil則監(jiān)聽(tīng)任何對(duì)象發(fā)送的通知)
     */
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationEnterBackground) name:UIApplicationDidEnterBackgroundNotification object:[UIApplication sharedApplication]];
    
    /* 添加應(yīng)用程序獲得焦點(diǎn)的通知監(jiān)聽(tīng)
     * name:監(jiān)聽(tīng)的通知名稱(chēng)
     * object:通知的發(fā)送者(如果指定nil則監(jiān)聽(tīng)任何對(duì)象發(fā)送的通知)
     * queue:操作隊(duì)列滥搭,如果制定非主隊(duì)線(xiàn)程隊(duì)列則可以異步執(zhí)行block
     * block:監(jiān)聽(tīng)到通知后執(zhí)行的操作
     */
    NSOperationQueue *operationQueue=[[NSOperationQueue alloc]init];
    [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidBecomeActiveNotification object:[UIApplication sharedApplication] queue:operationQueue usingBlock:^(NSNotification *note) {
        NSLog(@"Application become active.");
    }];
}

#pragma mark 應(yīng)用程序啟動(dòng)監(jiān)聽(tīng)方法
- (void)applicationEnterBackground{
    NSLog(@"Application enter background.");
}
@end
  • 當(dāng)然很多時(shí)候使用通知中心是為了添加自定義通知,并獲得自定義通知消息捣鲸。比如多視圖之間參數(shù)傳遞,其實(shí)利用自定義通知也可以進(jìn)行參數(shù)傳遞闽坡。通常一個(gè)應(yīng)用登錄后會(huì)顯示用戶(hù)信息栽惶,而登錄信息可以通過(guò)登錄界面獲取。下面就以這樣一種場(chǎng)景為例疾嗅,在主界面中添加監(jiān)聽(tīng)外厂,在登錄界面發(fā)送通知,一旦登錄成功將向通知中心發(fā)送成功登錄的通知代承,此時(shí)主界面中由于已經(jīng)添加通知監(jiān)聽(tīng)所以會(huì)收到通知并更新UI界面汁蝶。

主界面LTYViewController.m

//
//  LTYViewController.m
//  NotificationCenter
//

#import "LTYViewController.H"
#import "LTYoginViewController.h"
#define UPDATE_LGOGIN_INFO_NOTIFICATION @"updateLoginInfo"

@interface LTYViewController () {
    UILabel *_lbLoginInfo;
    UIButton *_btnLogin;
}

@end

@implementation LTYViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self setupUI];
}

- (void)setupUI{
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 100,320 ,30)];
    label.textAlignment = NSTextAlignmentCenter;
    label.textColor=[UIColor colorWithRed:23/255.0 green:180/255.0 blue:237/255.0 alpha:1];
    _lbLoginInfo = label;
    [self.view addSubview:label];
    
    UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
    button.frame=CGRectMake(60, 200, 200, 25);
    [button setTitle:@"登錄" forState:UIControlStateNormal];
    [button addTarget:self action:@selector(loginOut) forControlEvents:UIControlEventTouchUpInside];
    _btnLogin = button;
    
    [self.view addSubview:button];
}

- (void)loginOut{
    //添加監(jiān)聽(tīng)
    [self addObserverToNotification];
    
    LTYLoginViewController *loginController=[[LTYLoginViewController alloc] init];
    
    [self presentViewController:loginController animated:YES completion:nil];
}

/**
 *  添加監(jiān)聽(tīng)
 */
- (void)addObserverToNotification{
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateLoginInfo:) name:UPDATE_LGOGIN_INFO_NOTIFICATION object:nil];
}

/**
 *  更新登錄信息,注意在這里可以獲得通知對(duì)象并且讀取附加信息
 */
- (void)updateLoginInfo:(NSNotification *)notification{
    NSDictionary *userInfo=notification.userInfo;
    _lbLoginInfo.text=userInfo[@"loginInfo"];
    _btnLogin.titleLabel.text=@"注銷(xiāo)";
}

- (void)dealloc{
    //移除監(jiān)聽(tīng)
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}
@end

登錄界面LTYLoginViewController.m

//
//  LTYLoginViewController.m
//  NotificationCenter
//

#import "LTYLoginViewController.H"
#define UPDATE_LGOGIN_INFO_NOTIFICATION @"updateLoginInfo"

@interface LTYLoginViewController (){
    UITextField *_txtUserName;
    UITextField *_txtPassword;
}

@end

@implementation LTYLoginViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self setupUI];
}

/**
 *  UI布局
 */
- (void)setupUI{
    //用戶(hù)名
    UILabel *lbUserName=[[UILabel alloc]initWithFrame:CGRectMake(50, 150, 100, 30)];
    lbUserName.text=@"用戶(hù)名:";
    [self.view addSubview:lbUserName];
    
    _txtUserName=[[UITextField alloc]initWithFrame:CGRectMake(120, 150, 150, 30)];
    _txtUserName.borderStyle=UITextBorderStyleRoundedRect;
    [self.view addSubview:_txtUserName];
    
    //密碼
    UILabel *lbPassword=[[UILabel alloc]initWithFrame:CGRectMake(50, 200, 100, 30)];
    lbPassword.text=@"密碼:";
    [self.view addSubview:lbPassword];
    
    _txtPassword=[[UITextField alloc]initWithFrame:CGRectMake(120, 200, 150, 30)];
    _txtPassword.secureTextEntry=YES;
    _txtPassword.borderStyle=UITextBorderStyleRoundedRect;
    [self.view addSubview:_txtPassword];
    
    //登錄按鈕
    UIButton *btnLogin=[UIButton buttonWithType:UIButtonTypeSystem];
    btnLogin.frame=CGRectMake(70, 270, 80, 30);
    [btnLogin setTitle:@"登錄" forState:UIControlStateNormal];
    [self.view addSubview:btnLogin];
    [btnLogin addTarget:self action:@selector(login) forControlEvents:UIControlEventTouchUpInside];
    
    //取消登錄按鈕
    UIButton *btnCancel=[UIButton buttonWithType:UIButtonTypeSystem];
    btnCancel.frame=CGRectMake(170, 270, 80, 30);
    [btnCancel setTitle:@"取消" forState:UIControlStateNormal];
    [self.view addSubview:btnCancel];
    [btnCancel addTarget:self action:@selector(cancel) forControlEvents:UIControlEventTouchUpInside];
}

#pragma mark 登錄操作
-(void)login{
    if ([_txtUserName.text isEqualToString:@"ayuan"] && [_txtPassword.text isEqualToString:@"123"] ) {
        //發(fā)送通知
        [self postNotification];
        [self dismissViewControllerAnimated:YES completion:nil];
    }else{
        //登錄失敗彈出提示信息
        UIAlertView *alertView=[[UIAlertView alloc]initWithTitle:@"系統(tǒng)信息" message:@"用戶(hù)名或密碼錯(cuò)誤,請(qǐng)重新輸入论悴!" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil];
        [alertView show];
    }
    
}

#pragma mark 點(diǎn)擊取消
-(void)cancel{
    [self dismissViewControllerAnimated:YES completion:nil];
}

/**
 *  添加通知掖棉,注意這里設(shè)置了附加信息
 */
-(void)postNotification{
    NSDictionary *userInfo=@{@"loginInfo":[NSString stringWithFormat:@"Hello,%@!",_txtUserName.text]};
    NSLog(@"%@",userInfo);
    NSNotification *notification=[NSNotification notificationWithName:UPDATE_LGOGIN_INFO_NOTIFICATION object:self userInfo:userInfo];
   [[NSNotificationCenter defaultCenter] postNotification:notification];
//也可直接采用下面的方法
//    [[NSNotificationCenter defaultCenter] postNotificationName:UPDATE_LGOGIN_INFO_NOTIFICATION object:self userInfo:userInfo];

}
@end
  • 通知中心是一種低耦合設(shè)計(jì),和代理模式有異曲同工之妙膀估。相對(duì)于后者而言幔亥,通知中心可以將一個(gè)通知發(fā)送給多個(gè)監(jiān)聽(tīng)者,而每個(gè)對(duì)象的代理卻只能有一個(gè)察纯。當(dāng)然代理也有其優(yōu)點(diǎn)帕棉,例如使用代理代碼分布結(jié)構(gòu)更加清晰针肥,它不像通知一樣隨處都可以添加訂閱等,實(shí)際使用過(guò)程中需要根據(jù)實(shí)際情況而定香伴。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末慰枕,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子即纲,更是在濱河造成了極大的恐慌具帮,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件崇裁,死亡現(xiàn)場(chǎng)離奇詭異匕坯,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)拔稳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)葛峻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人巴比,你說(shuō)我怎么就攤上這事术奖。” “怎么了轻绞?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵采记,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我政勃,道長(zhǎng)唧龄,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任奸远,我火速辦了婚禮既棺,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘懒叛。我一直安慰自己丸冕,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布薛窥。 她就那樣靜靜地躺著胖烛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪诅迷。 梳的紋絲不亂的頭發(fā)上佩番,一...
    開(kāi)封第一講書(shū)人閱讀 51,182評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音罢杉,去河邊找鬼答捕。 笑死,一個(gè)胖子當(dāng)著我的面吹牛屑那,可吹牛的內(nèi)容都是我干的拱镐。 我是一名探鬼主播艘款,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼沃琅!你這毒婦竟也來(lái)了哗咆?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤益眉,失蹤者是張志新(化名)和其女友劉穎晌柬,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體郭脂,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡年碘,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了展鸡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片屿衅。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖莹弊,靈堂內(nèi)的尸體忽然破棺而出涤久,到底是詐尸還是另有隱情,我是刑警寧澤忍弛,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布响迂,位于F島的核電站,受9級(jí)特大地震影響细疚,放射性物質(zhì)發(fā)生泄漏蔗彤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一疯兼、第九天 我趴在偏房一處隱蔽的房頂上張望然遏。 院中可真熱鬧,春花似錦镇防、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至香拉,卻和暖如春啦扬,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背凫碌。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工扑毡, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人盛险。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓瞄摊,卻偏偏與公主長(zhǎng)得像勋又,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子换帜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容