学习内容

欢迎关注我的iOS学习总结——每天学一点iOS:https://github.com/practiceqian/one-day-one-iOS-summary

NSNitification与NotificationCenter(通知与通知中心)

  1. 通知的使用

    • [[NSNotificationCenter defaultCenter]addObserver:selfselector:@selector
      (noticeAction:) name:@"name" object:nil];

      注册观察者

    • NSNotification* notice = [NSNotification notificationWithName:@"name" object:nil userInfo:params];
      [[NSNotificationCenter defaultCenter]postNotification:notice];

      创建一个通知并发送

    • 观察者对象的注册一定要比通知的发送提前,否则的话会接收不到通知

  2. 通知和delegate的基本区别

    • 通知是允许多对多的,而delegate只能是一对一的
    • 通知的耦合度较低,发送方不需要知道通知方的任何情况,而delegate不行
    • 通知的效率比起delegate略差
  3. 通知是同步还是异步的?

    • postNotification:通知的发送总是会卡住当前线程,等待所有的observer对象执行(如果没有经过特殊处理,接收者对象的selector与postNotification在同一线程执行)完成后才会继续往下执行,所以是同步的
  4. 通知的移除

    • 在iOS9之前的版本中,如果对一个观察者对象在delloc之前之中没有从通知中心移除(remove)的话,会产生BAD_ACCESS野指针错误,导致crash
    • iOS9.0及以后的版本中不会造成crash
    • 原因:iOS9.0之前NSNotificationCenter持有的是observer的unsafe_uncertain指针,如果观察者对象已经被释放,但是没有从通知中心移除,那么postNotification方法会向观察者已经被回收的内存发送消息,就会造成野指针访问错误,iOS9.0以后,系统将unsafe_uncertain指针更改成了weak指针(对象回收,自动置nil),向nil发送消息不会差生任何问题(同时这里说明了oc是可以向nil发送消息的)
  5. 异步通知

    • [[NSNotificationQueue defaultQueue]enqueueNotification:notice postingStyle:NSPostASAP];
      ----------------------------------------------------------------------------------typedef NS_ENUM(NSUInteger, NSPostingStyle) {
      //空闲发送通知 当运行循环处于等待或空闲状态时,发送通知,对于不重要的通知可以使用。
      NSPostWhenIdle = 1,
      //尽快发送通知 当前运行循环迭代完成时,通知将会被发送,有点类似没有延迟的定时器。
      NSPostASAP = 2,
      //和postNotification一样是同步通知
      NSPostNow = 3
      };
    • 三种枚举类型代表三种发送方式(异步/同步都可)

    • 同样的,异步发送通知的话还可以使用开启一个新的线程的方式

    • dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
      [[NSNotificationCenter defaultCenter]postNotification:notice];
      });
  6. 通知的合并(待完善)

    • [[NSNotificationQueue defaultQueue] enqueueNotification:notice postingStyle:NSPostASAP coalesceMask:NSNotificationNoCoalescing forModes:nil];
      -----------------------------------------------------------------------------------
      typedef NS_OPTIONS(NSUInteger, NSNotificationCoalescing) {
      // 不合成
      NSNotificationNoCoalescing = 0,
      // 根据NSNotification的name字段进行合成
      NSNotificationCoalescingOnName = 1,
      // 根据NSNotification的object字段进行合成
      NSNotificationCoalescingOnSender = 2
      };
    • NSNotificationQueue除了有异步通知的能力之外,也能对当前队列的通知根据NSNotificationCoalescing类型进行合并,需要配合不同的NSRunLoopMode来进行

    • 通过合并通知我们可以用来保证相同的通知只被发送一次

  7. NSNotificationCenter实现原理

    • 通知中心用来管理通知的接收和发送,一开始将观察者注册到通知中心的通知调度表中,然后发送通知时利用标识符name和object识别出观察者,并调用相应的观察者方法,即传递消息(消息传递机制),如果是基于block创建的通知就调用NSNitification的block
  8. NSNotificationCenter使用block方式添加的观察者

    • - (id<NSObject>)addObserverForName:(NSString *)name
      object:(id)obj
      queue:(NSOperationQueue *)queue
      usingBlock:(void (^)(NSNotification *note))block
    • addObserver使用一个现存的对象作为观察者(一般为self),而使用block方法会创建一个匿名的(id)对象作为观察者,这个匿名对象会在指定的队列上去执行block

    • 如果queue为nil,则消息是默认在post线程中同步处理,即通知的post与转发是在同一线程中,不为nil的话就会在我们指定的队列中执行

    • 如果一个给定的通知触发了多个观察者的block操作,则这些操作会在各自的Operation Queue中被并发执行。所以我们不能去假设操作的执行会按照添加观察者的顺序来执行

    • 这个方法会返回一个匿名的观察者对象,我们需要手动释放这个对象。

iOS中对象间的五种传值方式(属性、代理、单例、Block、通知)

  1. 属性传值

    • 通过对象的公有属性进行传值
  2. 代理传值

    • 在委托方定义协议,协议中声明@required/@optional方法,声明一个代理属性,使用weak修饰符

    • 在代理方遵守协议,实现协议中的方法

    • 初始化委托对象,将委托对象的代理设置为self(代理对象自身)

    • 查看代理方是否实现了需要执行的选择子(SEL),如果实现了便开始执行

    • if ([self.delegate respondsToSelector:@selector(codeIOS)]) {
      // 让代理方执行协议中的方法
      [self.delegate SEL];
      }
    • 代理传值一般用于逆向传值,如:A控制器跳转到B控制器,B控制器为委托对象,A控制器为代理对象,B对象的代理为A对象,那么在B对象中可以传值给A对象,并在A对象中执行相应的方法

  3. 单例模式传值

    • 将一个类写成单例(常用dispatch_once),这样这个类就只含有全局唯一的实例,可以向整个程序提供实例
    • 如果一个类创建实例会耗费很多资源,那么可以将这个类写成单例类,节省alloc,init的时间
    • 在程序中如果多个类访问同一个变量,那么也可以将将该变量写入单例类中,调用起来更加方便
  4. 使用block代码块进行传值

    • 可以用于数据在多个对象间传递,网络请求的回调等

    • //在对象B中block作为方法参数
      - (void)getNextPage:(void (^)(BOOL))completeBlock{
      //block可以嵌套,第一层block可以在最后的block体中进行回调
      [self getPage:self.page complete:^(NSMutableArray *result) {
      if ([result count]) {
      self.page++;
      [self.musicList addObjectsFromArray:result];
      if (completeBlock) {
      //需要回调时,执行block
      completeBlock(true);
      }
      }else{
      if (completeBlock) {
      completeBlock(false);
      }
      }
      }];
      }
      ------------------------------------------------------------------------------
      //在对象A中isSucceed为回调回来的值
      [strongSelf.musicModel getNextPage:^(BOOL isSucceed) {
      if (isSucceed) {
      [strongSelf.waterFallCollectionView reloadData];
      }
      }];
  5. 通知传值

    • NSNotification的使用就是通知传值的一些用法

NSNotification,NSNotificationCenter的使用、iOS中五种对象间传值的方式的更多相关文章

  1. iOS中几种常用的数据存储方式

    自己稍微总结了一下下,方便大家查看 1.write直接写入文件的方法 永久保存在磁盘中,可以存储的对象有NSString.NSArray.NSDictionary.NSData.NSNumber,数据 ...

  2. iOS中4种判断网络请求的方式(系统状态栏、AFNetworking、Reachability、自定义)

    iOS 实时判断网络状态 方法一:利用系统状态栏判断网络状态 // 状态栏是由当前app控制的,首先获取当前app UIApplication *app = [UIApplication shared ...

  3. iOS页面间传值的方式(NSUserDefault/Delegate/NSNotification/Block/单例)

    iOS页面间传值的方式(NSUserDefault/Delegate/NSNotification/Block/单例) 实现了以下iOS页面间传值:1.委托delegate方式:2.通知notific ...

  4. 【转】iOS页面间传值的方式(Delegate/NSNotification/Block/NSUserDefault/单例)-- 不错

    原文网址:http://www.cnblogs.com/JuneWang/p/3850859.html iOS页面间传值的方式(NSUserDefault/Delegate/NSNotificatio ...

  5. iOS页面间传值的方式 (Delegate/NSNotification/Block/NSUserDefault/单例)

    iOS页面间传值的方式(Delegate/NSNotification/Block/NSUserDefault/单例)   iOS页面间传值的方式(NSUserDefault/Delegate/NSN ...

  6. Android中三种超实用的滑屏方式汇总(转载)

    Android中三种超实用的滑屏方式汇总   现如今主流的Android应用中,都少不了左右滑动滚屏这项功能,(貌似现在好多人使用智能机都习惯性的有事没事的左右滑屏,也不知道在干什么...嘿嘿),由于 ...

  7. Android中四种补间动画的使用示例(附代码下载)

    场景 Android中四种补间动画. 透明度渐变动画 旋转动画 缩放动画 平移动画 注: 博客: https://blog.csdn.net/badao_liumang_qizhi关注公众号 霸道的程 ...

  8. JavaScript中四种不同的属性检测方式比较

    JavaScript中四种不同的属性检测方式比较 1. 用in方法 var o = {x:1}; "x" in o; //true "y" in o; //fa ...

  9. 关于iOS中几种第三方对XML/JSON数据解析的使用

    Json XML 大数据时代,我们需要从网络中获取海量的新鲜的各种信息,就不免要跟着两个家伙打交道,这是两种结构化的数据交换格式.一般来讲,我们会从网络获取XML或者Json格式的数据,这些数据有着特 ...

随机推荐

  1. TensorFlow保存、加载模型参数 | 原理描述及踩坑经验总结

    写在前面 我之前使用的LSTM计算单元是根据其前向传播的计算公式手动实现的,这两天想要和TensorFlow自带的tf.nn.rnn_cell.BasicLSTMCell()比较一下,看看哪个训练速度 ...

  2. Mybatis对象关系映射 one2one,one2many,many2many

    MyBatis中的高级映射一般要借助select元素中的resultMap属性进行实现,通过此属性配置实现一对一,一对多等关系映射的实现 一对一映射:association 一对多映射:collect ...

  3. 干货:python面对对象类继承简介

    前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:python视觉算法 PS:如有需要Python学习资料的小伙伴可以加 ...

  4. sysbench安装和使用

    sysbench是一款测试工具 主要包括以下几种方式的测试: 1.cpu性能 2.磁盘io性能 3.调度程式性能 4.内存分配及传输速度 5.POSIX线程性能 6.数据库性能(OLTP基准测试)现在 ...

  5. idea ------- 源码调试运行

    1.创建一个 想学 的 ,使用单步调试进行一步步学习 调整系统资源 单步调试 (F7) ,进入不了源码,调整idea 让我们可以进入底层学习 想要在源码里面添加注释,要将引用的源文件指向,我们刚才复制 ...

  6. 乱 七 八 糟 $(n.)$

    \(2020/4/22\) 今天常规作业还是太慢了,白天似乎已经抓紧了,但总还能挤出时间来的.八点钟了还有物理和英语作业,回去又得很晚睡. 还是容易开小差,不过回忆了一下,今天化学课还是太懒散,其余的 ...

  7. Python - Python算法之冒泡算法的超简单实现

    [原创]转载请注明作者Johnthegreat和本文链接 冒泡排序在算法中算是最简单也最容易实现的,这里介绍一个非常简单实现的代码: def bubble_sort(ls): for first in ...

  8. HTML+CSS教程(六)浮动-float+定位-position+居中问题

    一.浮动(float)1.文档流:是指盒子按照 html 标签编写的顺序依次从上到下,从左到右排列,块元素占一行,行内元素在一行之内从左到右排列,先写的先排列,后写的排在后面,每个盒子都占据自己的位置 ...

  9. 使用 Python 控制自己的电脑和键盘是一种什么样的体验?python学习的正确姿势

    可能有时候你需要在电脑做一些重复的点击或者提交表单等操作,如果能通过 Python 预先写好相关的操作指令,让它帮你操作,然后你自己爱干嘛干嘛去,有点 “按键精灵” 的意思,是不是感觉有点爽呢? 那么 ...

  10. css3 文本控制自动换行

    text-overflow:ellipsis; white-space:nowrap; overflow:hidden;