zoukankan      html  css  js  c++  java
  • 通知NSNotification和KVO的使用

    1.通知NSNotification的使用
    NSNotification的名称在整个项目中必须是唯一的
    补充一个小知识,为了确保通知名称的唯一性,定义NSNotification的name时需要做些改变
    前边定义时如下

    #define AnyNotificationName   @"notiName"

    最好写成

    1 NSString * const AnyNotificationName = @"notiName";
    2 //也可写成下面的方式,这是等价的。可以通过打印内存地址来比较
    3 const NSString *AnyNotificationName = @"notiName";

    因为#define本质上还是NSString *,它与NSString * const的区别在于NSString *的指针可以改变指向(虽然内容不会改变),而NSString * const就是指向、内容都无法改变,更安全。因此在定义一些全局唯一性的属性时,推荐该法。

    更正:

    *******************************************************

    有时使用

    const NSString *AnyNotificationName = @"notiName";

    会给出警告sending 'const NSString *__strong' to parameter of type 'NSString' discards qualifiers
    这时就需要写成

    NSString * const AnyNotificationName = @"notiName";

    前者相当于指针本身不可修改,后者表示指针指向的内容不可修改。这两种写法的作用都是使AnyNotificationName只可读不可写。

    //指针本身不可变,写通知名称时推荐该法
    NSString * const kSomeConstantString = @"";
    
    //下边两种写法是等价的,表示指针指向的内容不可变。
    const NSString * kSomeConstantString = @"";
    NSString const * kSomeConstantString = @"";

    *******************************************************

    ①使前用先注册监听者,在下例中,当有名字为AnyNotificationName的通知发送到通知中心NSNotificationCenter后,就执行centerActive方法

     1 NSString * const AnyNotificationName = @"notiName";
     2 
     3 /**
     4 * 在通知中心(NSNotificationCenter)中注册监听者
     5 *
     6 * 通知中心(NSNotificationCenter)中注册观察者
     7 * addObserver 注册的观察者
     8 *
     9 * selector 收到通知后执行的方法
    10 * name     通知的名字,也是通知的唯一标识
    11 * object   这里的object不是传递给监听者的数据,通常为nil
    12 */
    13 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(centerActive:) name:AnyNotificationName object:nil];

    ②使用完毕后要从NSNotificationCenter移除观察者

    [[NSNotificationCenter defaultCenter] removeObserver:self name:AnyNotificationName object:nil];
    1 ///接收通知中心发送的通知后执行的方法
    2 -(void)centerActive:(NSNotification *) notification{
    3     if ([notification.name isEqualToString:AnyNotificationName]) {
    4         NSLog(@"通知中心发送的通知名称为:%@",notification.name);
    5     }
    6 }

    ③触发通知,在调用通知的时候会在整个项目中寻找符合该名称的通知,所以通知的name必须唯一

    1 NSArray *aaa = @[@"me",@"you",@"him"];
    2 //发送一个名为AnyNotificationName(notiName)的通知给观察者,这里的object才是传递给监听者的数据
    3 [[NSNotificationCenter defaultCenter] postNotificationName:AnyNotificationName object:aaa];

    下面是完整的例子

     1 NSString * const AnyNotificationName = @"notiName";
     2 
     3 @interface ViewController ()
     4 
     5 @end
     6 
     7 @implementation ViewController
     8 
     9 - (void)viewDidLoad {
    10     [super viewDidLoad];
    11     
    12     UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    13     [btn setTitle:@"发送通知" forState:UIControlStateNormal];
    14     [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    15     btn.frame = CGRectMake(100, 300, 100, 50);
    16     [btn addTarget:self action:@selector(sendNotification) forControlEvents:UIControlEventTouchUpInside];
    17     [self.view addSubview:btn];
    18     
    19 }
    20 
    21 /**
    22  * 通知中心(NSNotificationCenter)中注册观察者
    23  * addObserver 注册的观察者
    24  *
    25  * selector 收到通知后执行的方法
    26  * name     通知的名字,也是通知的唯一标识
    27  * object   这里不是传递给观察者的参数,通常为nil。
    28  */
    29 - (void)viewDidAppear:(BOOL)animated{
    30     [super viewDidAppear:animated];
    31 
    32     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(centerActive:) name:AnyNotificationName object:nil];
    33 }
    34 
    35 ///从通知中心(NSNotificationCenter)移除观察者
    36 -(void)viewDidDisappear:(BOOL)animated{
    37     [super viewDidDisappear:animated];
    38     
    39     [[NSNotificationCenter defaultCenter] removeObserver:self name:AnyNotificationName object:nil];
    40 }
    41 
    42 ///接收通知中心发送的通知
    43 -(void)centerActive:(NSNotification *) notification{
    44     if ([notification.name isEqualToString:AnyNotificationName]) {
    45         NSArray *a = notification.object;
    46         NSLog(@"通知中心发送的通知名称为:%@,数组为=%@",notification.name,a);
    47     }
    48 }
    49 
    50 ///利用通知中心发送通知,同时传递数据
    51 -(void)sendNotification{
    52     NSArray *aaa = @[@"me",@"you",@"him"];
    53     //发送一个名为AnyNotificationName(notiName)的通知给观察者
    54     [[NSNotificationCenter defaultCenter] postNotificationName:AnyNotificationName object:aaa];
    55 }
    56 
    57 @end

    2.知道了NSNotification,下面介绍下KVO,也是用的观察者模式,包括注册观察者、注销观察者等。如下:
    定义两个类,被观察者和观察者

    1 /** 被观察者,定义一个被观察的属性 */
    2 @interface KVOSubject : NSObject
    3 @property(nonatomic,copy) NSString *changedStr;
    4 @end
    5 
    6 /** 观察者 */
    7 @interface KVObserver : NSObject
    8 @end

    在观察者KVObserve的.m中实现一个方法,这个方法主要是用来当被观察的值发生改变时进行的操作

    1 -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
    2     //获取属性改变后的新值
    3     NSString *aaa = change[NSKeyValueChangeNewKey];
    4     NSLog(@"值发生了改变");
    5 }

    然后就可以进行观察行为

     1 -(void)activeKVO{
     2     KVOSubject *kvoSub = [[KVOSubject alloc]init];//被观察者
     3     KVObserver *kvoObser = [[KVObserver alloc]init];//观察者
     4     //注册观察者,forKeyPath中为KVOSubject的property属性
     5     [kvoSub addObserver:kvoObser forKeyPath:@"changedStr" options:NSKeyValueObservingOptionNew context:nil];
     6     //底下俩方法都可以改变值,所以打印两次
     7     kvoSub.changedStr = @"这是改变后的值";
     8     [kvoSub setValue:@"这是改变后的值" forKey:@"changedStr"];
     9     //注销观察者
    10     [kvoSub removeObserver:kvoObser forKeyPath:@"changedStr"];
    11 }
  • 相关阅读:
    git 拉取开发代码
    android webview
    H5 元素定位
    Python中模块
    服务器1
    活动
    宝塔面板-阿里部署
    最新版Xshell、Xftp注册机NetSarang
    最新版Navicat Premium激活,附激活工具
    9月29更新美版T-mobile版本iPhone7代和7P有锁机卡贴解锁方法
  • 原文地址:https://www.cnblogs.com/Apologize/p/4725059.html
Copyright © 2011-2022 走看看