zoukankan      html  css  js  c++  java
  • IOS NSNotification 通知

    一. 先看下官方对NSNotification通知的解释

    1. NSNotification 通知

     @interface NSNotification : NSObject <NSCopying, NSCoding>

      接口通知,继承NSObject,实现NSCopying,NSCoding协议

     A container for information broadcast through a notification center to all registered observers.

      通过通知中心向所有注册观察员进行信息广播的容器

     You don’t usually create your own notifications directly, but instead call the NSNotificationCenter methods.

      你不能使用init去创建,而是调用NSNotificationCenter下的方法

    2. NSNotificationCenter 通知中心

     A notification dispatch mechanism that enables the broadcast of information to registered observers.

      一种通知调度机制,该机制允许向注册观察员广播信息

     Each running app has a defaultCenter notification center, and you can create new notification centers to organize communications in particular contexts.

      每个运行的应用程序都有一个默认中心通知中心,您可以创建新的通知中心来组织特定上下文中的通信

     A notification center can deliver notifications only within a single program; if you want to post a notification to other processes or receive notifications from other processes, use NSDistributedNotificationCenter instead.

      通知中心只能在单个程序中传递通知;如果要将通知发布到其他进程或接收来自其他进程的通知,则使用NSdultDeNeTimeCenter代替

    3. addObserver(_:selector:name:object:) 添加观察者方法

      Adds an entry to the notification center's dispatch table with an observer, a selector, and an optional notification name and sender.

      使用观察者、选择器和可选通知名称和发送器向通知中心的调度表添加条目

    Declaration 声明

    *observer 观察者

      作为观察者注册的对象

    *aSelector 选择器

      当发出通知时,通知中心将向通知观察者发送通知的选择器

    *aName 注册观察员的通知的名称

      当NIL时,通知中心不使用通知的名称来决定是否将其传递给观察者

    *anObject 观察者希望接收的通知对象 

      当NIL时,通知中心不使用通知的发送方来决定是否将其传递给观察者

    4. postNotificationName(_:object:userInfo:) 发送通知消息的方法

      Creates a notification with a given name, sender, and information and posts it to the notification center.

      创建一个带有给定名称、发送者和信息的通知,并将其发布到通知中心

    1 - (void)postNotificationName:(NSNotificationName)aName
    2 
    3                           object:(id)anObject
    4 
    5                          userInfo:(NSDictionary *)aUserInfo;

     * aName

      通知的名称

    * anObject

      发布通知的对象

    * aUserInfo

      关于通知的可选信息

    5. removeObserver:name:object: 移除观察者的方法

      从通知中心的调度表中移除指定观察者的所有指定条目。

      如果你的应用程序瞄准了iOS 9和后来的Mac OS 10.11和以后,你就不需要在它的 dealloc 方法中注销观察者

    
    
    - (void)removeObserver:(id)observer;
    
    - (void)removeObserver:(id)observer          name:(NSString *)aName         object:(id)anObject;

     二. 通知使用

    示例背景: 用到两个ViewController,分别是 NotificationVC,TestVCViewController,当前代码写在NotificationVC中

    1. 注册通知
     1  // 初始化通知中心
     2     NSNotificationCenter * center = [NSNotificationCenter defaultCenter];
    3 // 注册通知 4 [center addObserver:self selector:@selector(methodTest:) name:nil object:nil]; 5 [center addObserver:self selector:@selector(sadNotif:) name:@"sad" object:nil]; 6 [center addObserver:self selector:@selector(smileNotif:) name:@"smile" object:nil]; 7 [center addObserver:self selector:@selector(sad2Notif:) name:@"sad" object:self]; 8 9 [center addObserver:test selector:@selector(testNotif:) name:nil object:nil]; 10 [center addObserver:test selector:@selector(sadNotif:) name:@"sad" object:nil]; 11 [center addObserver:test selector:@selector(smileNotif:) name:@"smile" object:nil]; 12 /* 用法说明 13 上面使用了两个监听器self,test,并且就参数三name,参数四object不同情况分别作出示例 14 [center addObserver:<#(nonnull id)#>
              selector:<#(nonnull SEL)#>
              name:<#(nullable NSNotificationName)#>
              object:<#(nullable id)#>]
    15 * 参数一 :监听器,即谁要接受这个通知 16 * 参数二 :回调方法,即接受通知时候,回调这个方法,作出响应 17 并把通知对象当作 参数 传入 18 * 参数三 : 通知的名称,标签 19 如果为nil,可以监听所有此类通知(具体还需要结合参数四) 20 如果有值,只监听这个名称的所有通知 21 * 参数四 :通知发布者 22 如果为nil,不关心是谁发布的通知,可根据参数三获取通知 23 如果有值,会获取这个值发布的通知,具体还需要看参数三是否一致 24 25 四个参数的作用: 26 参数一: 用于决定回调方法的位置,写在哪个类里面 27 参数二: 具体的回调方法,参数是通知对象 28 参数三: 是否需要监听指定的通知名称的通知 29 参数四: 是否需要监听指定的发布通告者的通知 30 31 注意: 如果通知名(参数三),发布通知者(参数四)都为nil 32 那么这个监听器的方法(参数二)可以回调所有此类通知 33 **/
    2.发布通知:
      // 发出通知
    
        [center postNotificationName:@"sad" object:nil  userInfo:@{@"title":@"伤心"}];
        [center postNotificationName:@"sad" object:self userInfo:@{@"title":@"伤心"}];
        [center postNotificationName:@"sad" object:test userInfo:@{@"title":@"伤心"}];
    
        [center postNotificationName:@"smile" object:nil  userInfo:@{@"title":@"开心"}];
        [center postNotificationName:@"smile" object:test userInfo:@{@"title":@"开心"}];
        [center postNotificationName:@"smile" object:self userInfo:@{@"title":@"开心"}];
    
        /* 发布通知
            [center postNotificationName:<#(nonnull NSNotificationName)#> 
                      object:<#(nullable id)#>
                     userInfo:<#(nullable NSDictionary *)#>] * 第一个参数,通知的方法名字,不能为nil * 第二个参数,通知的发布者,可以为nil * 第三个参数,通知所传递的信息,为字典格式
    */
    3. 回调方法:
    // self 中(NotificationVC)
    - (void)smileNotif:(NSNotification *)notif{
        NSLog(@"------1----%@/n",notif.userInfo);
    }
    - (void)sadNotif:(NSNotification *)notif{
        NSLog(@"------2----%@/n",notif.userInfo);
    }
    - (void)methodTest:(NSNotification *)notif{
        NSLog(@"------3----%@/n",notif.userInfo);
    }
    - (void)sad2Notif:(NSNotification *)notif{
        NSLog(@"------4----%@/n",notif.userInfo);
    }
    
    // TestVCViewController中
    - (void)testNotif:(NSNotification *)notif{
        NSLog(@"-----5-----%@/n",notif.userInfo);
    }
    - (void)smileNotif:(NSNotification *)notif{
        NSLog(@"-----6-----%@/n",notif.userInfo);
    }
    - (void)sadNotif:(NSNotification *)notif{
        NSLog(@"-----7-----%@/n",notif.userInfo);
    }
    
    // 由于打印的太多,这里不提供打印结果了,有兴趣的可以copy,断点打印,查看 参数不同 的 注册通知 之间的区别

      4. 移除通知:

    - (void)dealloc {
        [[NSNotificationCenter defaultCenter] removeObserver:test];
        [[NSNotificationCenter defaultCenter] removeObserver:self];
    }
    
    // 移除方法
    - (void)removeObserver:(id)observer;
    - (void)removeObserver:(id)observer name:(NSString *)aName object:(id)anObject;
    
     /* 
    removeObserver:是删除通知中心保存的调度表指定某个观察者的所有入口        removeObserver:name:object:是删除通知中心保存的调度表中某个观察者的指定某个入口
    注意参数notificationObserver为要删除的观察者,不能为nil
    **/
    
    // 通常这样写 在viewWillAppear 中 addObserver,在viewWillDisappear 中 removeObserver
    - (void)viewWillAppear:(BOOL)animated
    {
        [super viewWillAppear:animated];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(xxxx) name:@"xxxx" object:nil];
    }
    
    - (void)viewWillDisappear:(BOOL)animated
    {
        [super viewWillDisappear:animated];
        [[NSNotificationCenter defaultCenter] removeObserver:self name:@"xxxx" object:nil];
    }
    三. 扩展
    1.block 通知
     // 官方语法:
         - (id <NSObject>)addObserverForName:(nullable NSNotificationName)name 
                         object:(nullable id)obj 
                         queue:(nullable NSOperationQueue *)queue 
                      usingBlock:(void (^)(NSNotification *note))block API_AVAILABLE(macos(10.6),
     ios(4.0), watchos(2.0), tvos(9.0));
    
    /**
         // The return value is retained by the system, and should be held onto by the caller in
         // order to remove the observer with removeObserver: later, to stop observation.
         返回值由系统保留,并由调用方保存。
         顺序删除观测者,稍后,停止观察。
         *  参数一 : 通知名称
         *  参数二 : 监听者,即谁监听发出的通知
         *  参数三 : 队列,决定block在哪个线程中区执行
         如果传入nil,在发布通知的线程中去执行,即发布通知在哪个线程,block就在哪个线程中区执行
         如果是耗时操作,放在子线程
         *  参数四 : 监听到通知后的block回调
         
        注意 : block函数返回值(示例:上文声明的 id object),由当前调用方保存,最后要移除
         */
    
        object = [[NSNotificationCenter defaultCenter]addObserverForName:@"good" 
                                         object:self
                                          queue:nil
                                       usingBlock:^(NSNotification * _Nonnull note)
      {
    // 监听到通知会调用,不用单独写方法 NSLog(@"-----8-----%@/n",note.userInfo); }]; // object 为声明的 id object [center postNotificationName:@"good" object:self userInfo:@{@"good":@"好极了"}]; [center postNotificationName:@"sad" object:self userInfo:@{@"sad":@"坏死了"}];

    2.异步调用通知  

    即 通知放在异步方法中

    * NSNotificationCenter消息的接受线程是基于发送消息的线程的,即 同步的

    *  有时,你发送的消息可能不在主线程,但是操作UI必须在主线程,不然会出现不响应的情况。所以,在收到消息通知的时候,注意选择你要执行的线程

    *  一般用于通知中执行耗时操作,异步执行,保证UI主线程的流程,不会“假死,卡死”

    总结

    通知通常用于监听需求属性,当属性发生变化,发出通知,通过回调方法作出改变,响应通知

    参考博客:

    iOS中 本地通知/本地通知详解 韩俊强的博客 ps: 本地通知讲解的很详细,有兴趣可以下载他的demo)

    iOS中通知中心(NSNotificationCenter)的使用总结

    IOS中通知中心(NSNotificationCenter)的使用总结

    IOS 通知详解+异步发送和接收通知

      
  • 相关阅读:
    如何在intellj Idea中给新建的项目添加jar包?
    sell
    3D立体方块旋转图册
    npm run eject 命令后出现This git repository has untracked files or uncommitted changes错误
    video标签使用积累+背景视频+遇到问题(视频无法显示,不能自动播放,video自适应div,控件隐藏)
    webpack——react
    webpack——bable-loader,core,preset,编译es6
    webpack——打包JS
    简单的前端上传图片代码
    node——文件写入,文件读取
  • 原文地址:https://www.cnblogs.com/zhouDongdong/p/9406166.html
Copyright © 2011-2022 走看看