Objective-C之NSNotification Center(通知中心)

一,通知中心概述

    通知中心:它是IOS程序内部的一种消息广播机制,通过它,可以实现无引用关系的对象之间的通信。
    通知中心:他是基于观察者模式,它只能进行程序内部通信,不能跨应用程序进程通信,并且允许注册、删除观察者。
    通知中心:接受到消息后会根据设置,将消息发送给订阅者,这里的订阅者可以有多个。一个NSNotificationCenter可以有许多的通知消息NSNotification,对于每一                      个NSNotification可以有很多的观察者Observer来接收通知。 
    通知中心:与代理模式类似,都可以实现多个对象间通信,就是说通知中心可以将一个通知发送给多个监听者,而代理模式每个对象只能添加一个代理。
                    但无论是那种模式,都是一种低耦合的设计,实现对象间的通信。

                 

二,通知中心的相关类

NSNotificationCenter:整个架构的大脑,由该类实现了观察者模式,并给开发者提供了诸如注册、删除观察者的接口,我们可以通过一个单例来获得它的实例(注,一个程序内部只有一个NSNotificationCenter实例对象)。

NSNotification:这是消息携带的载体,通过它,可以把消息内容传递给观察者。其中:name对应消息名称标示。object一般是发送者本身、dictionary则是传递的消息内容。

三,通知中心的使用方法

 创建通知中心对象 

+ (NSNotificationCenter *)defaultCenter
       通过单例模式,创建通知中心对象(在程序内部,这个对象是唯一的)
 发布通知:

    1.方法:

-(void)postNotification:(NSNotification *)notification;
       //发布一个notification通知,可在notification 对象中设置通知的名称,通知发布者,额外信息等
       -(void)postNotificationName:(NSString *)aName object:(id)anObject;
       //发布一个名称为aName的通知,anObject为这个通知的发布者
       -(void)postNotificationName:(NSString *)aName object:(id) anObject  userInfo:          (NSDictionary *)aUserInfo;
       //发布一个名称为aName的通知,anObject为这个通知的发布者,aUserInfo为额外信息
  注册通知:监听必须要放在发布之前(就像是送牛奶,只有你先定了,才给你发送)
[notificationCenter addObserver:<#(id)#> selector:<#(SEL)#> name:<#(NSString *)#> object:<#(id)#>]
       参数1:要监听通知的对象
       参数2:该对象的那个方法来监听通知
       参数3:被监听的通知的名称(传统的做法是采用和应用程序相关的两个或者三个字母作为通知名称的前缀)
        (注意: 1>假如没有指定参数三或者指定参数三为nil,但是指定了参数四为sender,那么表示sender发布的所有通知都会监听到.
                  2>如果指定了参数3(指定要监听某个通知,但是没有指定参数4(参数4为nil),那么表示无论是那个对象发布的与给定的通知名称相同的通知都会被监听到))
                  3>如果参数3 和参数4都是nil,那么所有对象发布的所用通知,这个方法都会监听的到
       参数4:发布通知的对象

  注意:比方说,注册通知如下    

[[NSNotificationCenter defaultCenter] addObserver:self   selector:@selector(viewDidChange:)  name:NSWindowDidBecomeMainNotification object:nil];
    问题点1:

      这里保证了self定义了viewDidChange:方法。而对于一个任意的观察者observer,不能保证其对应的selector有viewDidChange:

   解决方法:

       可采用[observer respondsToSelector:@selector(viewDidChange:)]] 进行检查。所以完整的添加观察者过程为:

 if([observer respondsToSelector:@selector(viewDidChange:)]){
        [[NSNotificationCenter defaultCenter] addObserver:observer selector:@selector(viewDidChange:) name:NSWindowDidBecomeMainNotification object:nil];
   }

 移除通知:在监听者内部重写dealloc方法(ARC中禁止发送[super  dealloc]消息给父类,MRC中可以) 

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

 获取通知内容:
 例子:

-(void)m1:(NSNotification *)noteINfo;
具体的通知信息:
noteInfo.name  //监听到的通知的名称
noteInfo.object //监听到的通知是那个对象发布的
noteInfo.userInfo  //这是一个字典,这个字典中就包含了通知的具体内容
四,NSNotificationCenter 传递带参数的通知

    注册通知 

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

在dealloc里面移除这个通知的注册: 
[[NSNotificationCenter  defaultCenter] removeObserver:self  name:str object:nil];
一般在使用NSNotificationCenter的时候不使用参数,但是有些时候需要使用参数。
    发布通知
[[NSNotificationCenter defaultCenter] postNotificationName:@"test" object:searchFriendArray];
   接收参数并获取传递的参数
postNotificationName:通知的名字,也是通知的唯一标示,编译器就通过这个找到通知的。object:传递的参数
- (void) test:(NSNotification*) notification{
    searchFriendArrary = [notification object];//通过这个获取到传递的对象
} 

五.知识点补充:

  NSNotificationCenter
  概念: 对于这个没必要多说,就是一个消息通知机制,类似广播。观察者只需要向消息中心注册感兴趣的东西,当有地方发出这个消息的时候,通知中心会发送给注册这个消息的对象。这样也起到了多个对象之间解耦的作用。 
  注意点:1> 向NSNotificationCenter中addObserver后,并没有对这个对象进行引用计数加1操作,所以它只是保存了地址.
              2> addObserver后,必须要有remove; 但是在视图控制器中,不移除也不会奔溃,因为试图控制器在post的时候回自动帮助我们把注册的通知给移除掉.测试方法为给通知中心加类别,重写它的remove方法.
              3>注册通知和移除通知一定要成双成对出现. 其中移除写在前面,注册写在后面,最终移除写在dealloc中(为什么呢? 这是因为,我们不知道,系统中有没有同样的通知,所以确保万一,及移动要在注册之前进行清除一次. 最终我们再在dealloc中进行通知的彻底移除);
              4>NSNotificationCenter消息的接受线程是基于发送消息的线程的。也就是同步的,因此,有时候,你发送的消息可能不在主线程,而大家都知道操作UI必须在主线程,不然会出现不响应的情况。所以,在你收到消息通知的时候,注意选择你要执行的线程。

 ios系统消息通知:

  1> 键盘
     1、UIKeyboardWillShowNotification-将要弹出键盘
     2、UIKeyboardDidShowNotification-显示键盘
     3、UIKeyboardWillHideNotification-将要隐藏键盘
     4、UIKeyboardDidHideNotification-键盘已经隐藏
     5、UIKeyboardWillChangeFrameNotification-键盘将要改变frame
     6、UIKeyboardDidChangeFrameNotification-键盘已经改变frame
  2>窗口
    1、UIWindowDidBecomeVisibleNotification-窗口可见
    2、UIWindowDidBecomeHiddenNotification-窗口隐藏
    3、UIWindowDidBecomeKeyNotification
    4、UIWindowDidResignKeyNotification
  3>程序消息
    1、UIApplicationDidBecomeActiveNotification-程序从后台激活
    2、UIApplicationDidChangeStatusBarFrameNotification-状态栏frame改变
    3、UIApplicationDidChangeStatusBarOrientationNotification-状态栏方向改变
    4、UIApplicationDidEnterBackgroundNotification-进入后台
    5、UIApplicationDidFinishLaunchingNotification-程序加载完成
    6、UIApplicationDidReceiveMemoryWarningNotification-内存警告
    7、UIApplicationProtectedDataDidBecomeAvailable
    8、UIApplicationProtectedDataWillBecomeUnavailable
    9、UIApplicationSignificantTimeChangeNotification 重要的时间变化(新的一天开始或时区变化)
  10、UIApplicationWillChangeStatusBarOrientationNotification-将要改变状态栏方向
  11、UIApplicationWillChangeStatusBarFrameNotification-将要改变状态栏frame
  12、UIApplicationWillEnterForegroundNotification
  13、UIApplicationWillResignActiveNotification
  14、UIApplicationWillTerminateNotification
 4>电池、方向、传感器
   1、UIDeviceBatteryLevelDidChangeNotification //电池电量
   2、UIDeviceBatteryStateDidChangeNotification //电池状态
   3、UIDeviceOrientationDidChangeNotification //方向
   4、UIDeviceProximityStateDidChangeNotification //近距离传感器
 5>音视频
   1、MPMediaLibraryDidChangeNotification
   2、MPMusicPlayerControllerPlaybackStateDidChangeNotification
   3、MPMusicPlayerControllerNowPlayingItemDidChangeNotification
   4、MPMusicPlayerControllerVolumeDidChangeNotification
 6>其他
  1、NSUserDefaultsDidChangeNotification 用户默认设置变化
  2、NSCurrentLocaleDidChangeNotification 本地化语言变化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值