• iOS NSNotificationCenter详解


    通知中心的特点:

    1:同步执行

    2: 一对多发送消息

    3: 降低程序耦合度

    通知中心是单例,目的就是从任意一个发送消息到任意一个接收者,是同步执行的。

    那么什么是同步呢?

    用网上经典的说法,就是我叫朋友去吃饭,如果他没来,我就继续叫,等到他出来了我们才一起去吃,这就是同步;如果我叫朋友去吃饭,叫完无论他有没有来,我都先去吃饭,

    这就是异步;在通知中心里就是每发送一次消息,要等消息被接收并完全执行完里面的方法,然后才返回来发送第二条消息,这就是同步,即通知中心发送消息是一条一条发送,而且是上条消息执行完才执行下一条的。

    NSNotificationCenter的使用:
    步骤主要有三个:注册通知、发送广播、销毁广播   另外还有创建通知

    默认都是用defaultCenter,而通知不需要时可省略

    先介绍一下声明方法:

    创建一个通知的方法:

    第一种方法三个参数: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];

     简化使用时,可用2、3、4步即可,例子就需要修改,可以根据需要从注册里添加object,和发送的通知里带信息

    这里还涉及到观察者的注册和销毁问题

    观察者的创建和销毁要成对存在,一次添加对应一次销毁

    创建的位置如   viewWillAppear  和  viewDidAppear, 销毁的位置如   viewWillDisappear 、viewDidDisappear  和 dealloc

    就是在页面出现的时候注册通知,页面消失时移除通知。一定要成双成对出现,如果你只在viewWillAppear 中 addObserver没有在viewWillDisappear 中 removeObserver那么当消息发生的时候,你的方法会被调用多次。

    当然详细的还是根据需要的来进行修改,如有些通知是在整个工程里用到,创建在appDelegate里,如果通知中心在其他地方有需要用到而不用马上销毁时,使用完成时再进行

    销毁,从实际情况确定。

    NSNotificationCenter就到这了,如果有地方说得不对的话,欢迎大家指出

  • 相关阅读:
    redis 五种数据结构详解(string,list,set,zset,hash)
    推荐一个同步Mysql数据到Elasticsearch的工具
    一些经验,用来鉴别不太靠谱的公司或工作(面试是双向的,是你最好的了解这个公司的机会)
    OpenSSL 使用 base64 编码/解码(liang19890820)
    Qt之QEvent(所有事件的翻译)
    Go 在 Windows 上用户图形界面 GUI 解决方案 Go-WinGUI 国产(使用cef 内核)
    卷积神经网络CNN
    Event Driven Architecture
    wineshark分析抓取本地回环包
    僵尸进程与孤儿进程
  • 原文地址:https://www.cnblogs.com/fcug/p/5312224.html
Copyright © 2020-2023  润新知