iOS 通知多线程的使用

2019 年 4 月 27 日 CocoaChina

一、通知使用的回顾


1.1、通知使用一


添加通知


/**
  添加通知
  observer:观察者
  aSelector:只要一监听到通知就会调用观察者这个方法
  aName:通知名称
  anObject:谁发出的通知或者是一些参数
  - (void)addObserver:(id)observer selector:(SEL)aSelector name:(nullable NSNotificationName)aName object:(nullable id)anObject;
 */

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


发送通知


/**
  发送通知
  aName:通知名称
  anObject:谁发出的通知或者是一些参数
  - (void)postNotificationName:(NSNotificationName:)aName object:(nullable id)anObject;
 */

[[NSNotificationCenter defaultCenter]postNotificationName:@"note" object:nil];


接收通知的消息


-(void)reciveNote:(NSNotification *)notify{

    NSLog(@"通知");
}


移除通知


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


1.2、通知使用二(block的通知)


定义监听的返回值


@property (nonatomicweakid observe;


添加通知


/**
name:通知名称
object:谁发出的通知
queue:决定block在哪个线程执行,nil:在发布通知的线程中执行
usingBlock:只要监听到通知,就会执行该blocl
  - (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));
注意:一定要移除通知
 */

self.observe = [[NSNotificationCenter defaultCenter]addObserverForName:@"note" object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {

     // 只要监听到通知就会被调用
     NSLog(@"当前的线程=%@",[NSThread currentThread]);

     NSLog(@"%@",self);

}];


发送通知


/**
  发送通知
  aName:通知名称
  anObject:谁发出的通知
  - (void)postNotificationName:(NSNotificationName)aName object:(nullable id)anObject;
 */

[[NSNotificationCenter defaultCenter]postNotificationName:@"note" object:nil];


移除通知


[[NSNotificationCenter defaultCenter]removeObserver:self.observe];

注意:一定要移除通知



二、通知多线程的使用


2.1、利用 1.1 的通知方式


// 监听通知:异步
dispatch_async(dispatch_get_global_queue(00), ^{

   [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(reciveNote:) name:@"note" object:nil];
});


异步  发送通知


dispatch_async(dispatch_get_global_queue(00), ^{

   [[NSNotificationCenter defaultCenter]postNotificationName:@"note" object:nil];
});


提示:接收通知的方法里面打印的是:子线程



同步  发送通知


dispatch_sync(dispatch_get_global_queue(00), ^{

   [[NSNotificationCenter defaultCenter]postNotificationName:@"note" object:nil];
});


提示:接收通知的方法里面打印的是:主线程



接收通知的消息


-(void)reciveNote:(NSNotification *)notify{

   NSLog(@"当前接收通知的线程=%@",[NSThread currentThread]);
}


提示:很多时候我们可能不知道发送通知的线程,我们需要在接收通知的方法里面进行更新UI,我们可以在接收方法里面使用主线程,如下



-(void)reciveNote:(NSNotification *)notify{

    NSLog(@"当前接收通知的线程=%@",[NSThread currentThread]);
    dispatch_sync(dispatch_get_main_queue(), ^{
          // 在此刷新UI
    });
}


移除通知


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


结论:不管添加通知在主线程还是子线程,接收通知的方法所在的线程是由发送通知的线程决定的。


2.2、利用 1.2 的通知方式:和上面的一样,我直接说有关刷新的问题


self.observe = [[NSNotificationCenter defaultCenter]addObserverForName:@"note" object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
      // 只要监听到通知就会被调用
      NSLog(@"当前的线程=%@",[NSThread currentThread]);
      NSLog(@"%@",self);
}];


分析:如果上面的是:queuenil,那么block里面的线程是由发送通知的线程决定,那么如果block里面是子线程我们就无法刷新UI了,解决办法是把 nil 改为[NSOperationQueue mainQueue],不管发送通知的线程是什么,block里面都是主线程,如下


self.observe = [[NSNotificationCenter defaultCenter]addObserverForName:@"note" object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
    // 只要监听到通知就会被调用
    NSLog(@"当前的线程=%@",[NSThread currentThread]);
}];


最后这是调试的 demo


作者:IIronMan

链接:https://www.jianshu.com/p/2c0b863c202f


本公众号转载内容已尽可能注明出处,如未能核实来源或转发内容图片有权利瑕疵的,请及时联系本公众号进行修改或删除【联系方式QQ : 3442093904  邮箱:support@cocoachina.com】。文章内容为作者独立观点,不代表本公众号立场。版权归原作者所有,如申请授权请联系作者,因文章侵权本公众号不承担任何法律及连带责任。

---END---

登录查看更多
0

相关内容

【2020新书】实战R语言4,323页pdf
专知会员服务
101+阅读 · 2020年7月1日
【实用书】学习用Python编写代码进行数据分析,103页pdf
专知会员服务
195+阅读 · 2020年6月29日
【2020新书】使用高级C# 提升你的编程技能,412页pdf
专知会员服务
58+阅读 · 2020年6月26日
还在修改博士论文?这份《博士论文写作技巧》为你指南
【芝加哥大学】可变形的风格转移,Deformable Style Transfer
专知会员服务
31+阅读 · 2020年3月26日
【干货书】流畅Python,766页pdf,中英文版
专知会员服务
226+阅读 · 2020年3月22日
【阿里巴巴】 AI编译器,AI Compiler @ Alibaba,21页ppt
专知会员服务
45+阅读 · 2019年12月22日
强化学习最新教程,17页pdf
专知会员服务
177+阅读 · 2019年10月11日
PHP使用Redis实现订阅发布与批量发送短信
安全优佳
7+阅读 · 2019年5月5日
已删除
架构文摘
3+阅读 · 2019年4月17日
I2P - 适用于黑客的Android应用程序
黑白之道
32+阅读 · 2019年3月6日
如何用GitLab本地私有化部署代码库?
Python程序员
9+阅读 · 2018年12月29日
Android P正式发布,你需要尽快做适配了
前端之巅
3+阅读 · 2018年8月7日
用Python调用百度OCR接口实例
数据挖掘入门与实战
16+阅读 · 2018年1月29日
教你用Python来玩跳一跳
七月在线实验室
6+阅读 · 2018年1月2日
iOS高级调试&逆向技术
CocoaChina
3+阅读 · 2017年7月30日
Deep Learning for Generic Object Detection: A Survey
Arxiv
13+阅读 · 2018年9月6日
Large-Scale Study of Curiosity-Driven Learning
Arxiv
8+阅读 · 2018年8月13日
Arxiv
3+阅读 · 2018年3月13日
VIP会员
相关VIP内容
【2020新书】实战R语言4,323页pdf
专知会员服务
101+阅读 · 2020年7月1日
【实用书】学习用Python编写代码进行数据分析,103页pdf
专知会员服务
195+阅读 · 2020年6月29日
【2020新书】使用高级C# 提升你的编程技能,412页pdf
专知会员服务
58+阅读 · 2020年6月26日
还在修改博士论文?这份《博士论文写作技巧》为你指南
【芝加哥大学】可变形的风格转移,Deformable Style Transfer
专知会员服务
31+阅读 · 2020年3月26日
【干货书】流畅Python,766页pdf,中英文版
专知会员服务
226+阅读 · 2020年3月22日
【阿里巴巴】 AI编译器,AI Compiler @ Alibaba,21页ppt
专知会员服务
45+阅读 · 2019年12月22日
强化学习最新教程,17页pdf
专知会员服务
177+阅读 · 2019年10月11日
相关资讯
PHP使用Redis实现订阅发布与批量发送短信
安全优佳
7+阅读 · 2019年5月5日
已删除
架构文摘
3+阅读 · 2019年4月17日
I2P - 适用于黑客的Android应用程序
黑白之道
32+阅读 · 2019年3月6日
如何用GitLab本地私有化部署代码库?
Python程序员
9+阅读 · 2018年12月29日
Android P正式发布,你需要尽快做适配了
前端之巅
3+阅读 · 2018年8月7日
用Python调用百度OCR接口实例
数据挖掘入门与实战
16+阅读 · 2018年1月29日
教你用Python来玩跳一跳
七月在线实验室
6+阅读 · 2018年1月2日
iOS高级调试&逆向技术
CocoaChina
3+阅读 · 2017年7月30日
Top
微信扫码咨询专知VIP会员