你真的了解NSNotificationCenter吗?
一:首先查看一下关于NSNotificationCenter的定义
@interface NSNotificationCenter : NSObject {@packagevoid * __strong _impl;void * __strong _callback;void *_pad[11]; }//单例获得消息中心对象 + (NSNotificationCenter *)defaultCenter;//增加消息监听 第一个参数是观察者为本身,第二个参数表示消息回调的方法,第三个消息通知的名字,第四个为nil表示表示接受所有发送者的消息 - (void)addObserver:(id)observer selector:(SEL)aSelector name:(nullable NSString *)aName object:(nullable id)anObject;//发送通知 三种方式 - (void)postNotification:(NSNotification *)notification; - (void)postNotificationName:(NSString *)aName object:(nullable id)anObject; - (void)postNotificationName:(NSString *)aName object:(nullable id)anObject userInfo:(nullable NSDictionary *)aUserInfo;//移除监听 - (void)removeObserver:(id)observer; //移除监听特定消息 - (void)removeObserver:(id)observer name:(nullable NSString *)aName object:(nullable id)anObject;//增加监听 又提供了一个以block方式实现的添加观察者的方法 - (id <NSObject>)addObserverForName:(nullable NSString *)name object:(nullable id)obj queue:(nullable NSOperationQueue *)queue usingBlock:(void (^)(NSNotification *note))block NS_AVAILABLE(10_6, 4_0);@end
每一个程序都有一个自己的通知中心,即NSNotificationCenter对象。NSNotificationCenter这个也是我们平常用到的相关消息内容操作;NSNotificationCenter是一个单列,我们可以通过defaultCenter来获取到通知中心这个单列;通知中心实际上是iOS程序内部之间的一种消息广播机制,主要为了解决应用程序内部不同对象之间解耦而设计。它是基于观察者模式设计的,不能跨应用程序进程通信,当通知中心接收到消息之后会根据内部的消息转发表,将消息发送给订阅者;
知识点1:消息的运用步骤
1:创建通知并发送
NSNotification *notification =[NSNotification notificationWithName:@"qjwallet" object:nil userInfo:nil];//通过通知中心发送通知[[NSNotificationCenter defaultCenter] postNotification:notification];
2:在接收的页面注册消息通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(qjwalletNotification:) name:@"qjwallet" object:nil];
3:处理接收到的内容,并进行操作
- (void)qjwalletNotification:(NSNotification *)text{//NSLog(@"%@",text.userInfo[@"orderid"]);NSLog(@"-----接收到通知------"); }
4:移除消息通知
-(void)dealloc {[[NSNotificationCenter defaultCenter]removeObserver:self name:@"qjwallet" object:nil]; }
知识点2:关于创建通知并发送另外两个方法
方法1:[[NSNotificationCenter defaultCenter] postNotificationName:@"First" object:@"博客园"]; 方法2: NSDictionary *dict=[[NSDictionary alloc]initWithObjects:@[@"keso"] forKeys:@[@"key"]]; [[NSNotificationCenter defaultCenter] postNotificationName:@"Second" object:@"http://www.cnblogs.com" userInfo:dict];
上面两个方法已经把NSNotification对象封装一层,所以只要传入相关的对象属性就可以;
知识点3:通过NSNotificationCenter注册通知NSNotification,viewDidLoad中
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationFirst:) name:@"First" object:nil];[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationSecond:) name:@"Second" object:nil];
-(void)notificationFirst:(NSNotification *)notification{NSString *name=[notification name];NSString *object=[notification object];NSLog(@"名称:%@----对象:%@",name,object); }-(void)notificationSecond:(NSNotification *)notification{NSString *name=[notification name];NSString *object=[notification object];NSDictionary *dict=[notification userInfo];NSLog(@"名称:%@----对象:%@",name,object);NSLog(@"获取的值:%@",[dict objectForKey:@"key"]); }
知识点4:移除通知消息
-(void)dealloc{NSLog(@"观察者销毁了");[[NSNotificationCenter defaultCenter] removeObserver:self]; }也可以针对某一个进行移除:[[NSNotificationCenter defaultCenter] removeObserver:self name:@"First" object:nil];
知识点5:如果notificationName为nil,则会接收所有的通知(如果notificationSender不为空,则接收所有来自于notificationSender的所有通知)。如代码清单1所示。如果notificationSender为nil,则会接收所有notificationName定义的通知;否则,接收由notificationSender发送的通知。监听同一条通知的多个观察者,在通知到达时,它们执行回调的顺序是不确定的,所以我们不能去假设操作的执行会按照添加观察者的顺序来执行
知识点6:addObserverForName监听消息处理跟addObserver的差别
在前面addObserver有介绍它的四个参数作用,分别指定了通知的观察者、处理通知的回调、通知名及通知的发送对象;而addObserverForName同样是监听消息处理,只是它并没有观察者,却多出一个队列跟一个block的处理;addObserverForName参数说明,name和obj为nil时的情形与前面一个方法addObserver是相同的。如果queue为nil,则消息是默认在post线程中同步处理,即通知的post与转发是在同一线程中;但如果我们指定了操作队列,情况就变得有点意思了,我们一会再讲。block块会被通知中心拷贝一份(执行copy操作),以在堆中维护一个block对象,直到观察者被从通知中心中移除。所以,应该特别注意在block中使用外部对象,避免出现对象的循环引用。如果一个给定的通知触发了多个观察者的block操作,则这些操作会在各自的Operation Queue中被并发执行。所以我们不能去假设操作的执行会按照添加观察者的顺序来执行。该方法会返回一个表示观察者的对象,记得在不用时释放这个对象。
实例在指定队列中接收通知:
@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];[[NSNotificationCenter defaultCenter] addObserverForName:TEST_NOTIFICATION object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {NSLog(@"receive thread = %@", [NSThread currentThread]);}];dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{NSLog(@"post thread = %@", [NSThread currentThread]);[[NSNotificationCenter defaultCenter] postNotificationName:TEST_NOTIFICATION object:nil];}); }@end
在这里,我们在主线程里添加了一个观察者,并指定在主线程队列中去接收处理这个通知。然后我们在一个全局队列中post了一个通知。我们来看下输出结果:
post thread = <NSThread: 0x7ffe0351f5f0>{number = 2, name = (null)} receive thread = <NSThread: 0x7ffe03508b30>{number = 1, name = main}
可以看到,消息的post与接收处理并不是在同一个线程中。如上面所提到的,如果queue为nil,则消息是默认在post线程中同步处理;
二:关于NSNotification的定义
@interface NSNotification : NSObject <NSCopying, NSCoding> //这个成员变量是这个消息对象的唯一标识,用于辨别消息对象 @property (readonly, copy) NSString *name; // 这个成员变量定义一个对象,可以理解为针对某一个对象的消息,代表通知的发送者 @property (nullable, readonly, retain) id object; //这个成员变量是一个字典,可以用其来进行传值 @property (nullable, readonly, copy) NSDictionary *userInfo;// 初始化方法 - (instancetype)initWithName:(NSString *)name object:(nullable id)object userInfo:(nullable NSDictionary *)userInfo NS_AVAILABLE(10_6, 4_0) NS_DESIGNATED_INITIALIZER; - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER;@end
NSNotification顾名思义就是通知的作用,一个对象通知另外一个对象,可以用来传递参数、通信等作用,与delegate的一对一不同,通知是一对多的。在一个对象中注册了通知,那么其他任意对象都可以来对这个对象发出通知。因为属性都是只读的,如果要创建消息时要用下面NSNotification (NSNotificationCreation)分类相应的方法进行初始化;
三:NSNotification (NSNotificationCreation)分类
@interface NSNotification (NSNotificationCreation)+ (instancetype)notificationWithName:(NSString *)aName object:(nullable id)anObject; + (instancetype)notificationWithName:(NSString *)aName object:(nullable id)anObject userInfo:(nullable NSDictionary *)aUserInfo;- (instancetype)init /*NS_UNAVAILABLE*/; /* do not invoke; not a valid initializer for this class */@end
上面为初使化NSNotification对象,用于消息的发送对象;
最近有个妹子弄的一个关于扩大眼界跟内含的订阅号,每天都会更新一些深度内容,在这里如果你感兴趣也可以关注一下(嘿对美女跟知识感兴趣),当然可以关注后输入:github 会有我的微信号,如果有问题你也可以在那找到我;当然不感兴趣无视此信息;
转载于:https://www.cnblogs.com/wujy/p/5825690.html
你真的了解NSNotificationCenter吗?相关推荐
- html转换成word qt,PHP 将HTML转成PDF文件,HTML 转word,Word 转Html
html转 PDF 用MPDF ,Word转Html 纯PHP的方法暂未找到Word直接转PDF的方法 可以使用 LibreOffice 6.1 (Liunx,win) 皆可使用 Html转成PD ...
- 类似 Observer Pattern 的 NSNotificationCenter (实例)
NSNotificationCenter 是 Cococa消息中心,统一管理单进程内不同线程的消息通迅,其职责只有两个: 1,提供"观查者们"对感兴趣消息的监听注册 [[NSNo ...
- 系统架构升级要不要上微服务?历“久”弥新微服务——你真的需要升级微服务架构吗
在 <微服务架构设计模式> 一书中,作者总结了关于微服务的一些"重点",原文如下: 中国企业和开发者对微服务架构的热情让我印象深刻.但如同我给所有客户的忠告一样,我想对 ...
- 制作欧比旺·克诺比逼真的CG角色学习教程
艺术站-制作欧比旺·克诺比逼真的Cg角色 大小解压后:4.98G 含课程素材文件 1920X1080 .mp4 语言:英语+中英文字幕(根据原英文字幕机译更准确) 课程获取:制作欧比旺·克诺比逼真的C ...
- SQL Server中SELECT会真的阻塞SELECT吗?
在SQL Server中,我们知道一个SELECT语句执行过程中只会申请一些意向共享锁(IS) 与共享锁(S), 例如我使用SQL Profile跟踪会话86执行SELECT * FROM dbo.T ...
- android 手机推荐,2018年安卓机皇推荐,这几款是真的不错
原标题:2018年安卓机皇推荐,这几款是真的不错 不知不觉,2018年悄然过去大半,今年的手机市场发展情况可以用日新月异来描述了.回看前半年,安卓手机市场风起云涌,不断涌现出口碑和质量俱佳新产品. O ...
- 按下enter键在各个文本框中切换焦点_你真的了解Enter键吗?请先学习本文后再回答...
回车键Enter,应该是工作办公和娱乐中应用最多的键了,但是你真的了解吗? 一.回车键Enter:粘贴数据. 目的:粘贴复制的数据. 方法: 1.选定目标单元格并复制数据. 2.在目标单元格按Ente ...
- 打牌软件可以控制吗_使用crm软件真的可以帮助企业省钱吗
使用crm软件真的可以帮助企业省钱吗 大多数企业管理者认为:"客户关系系统有什么用?真的可以帮助企业发展吗?自己做一套excel版本不就行了"其实,不以为然,当我们去寻找用户时或者 ...
- 基于web创建逼真的3D图形 | CSS技巧
在成为一名web开发者之前,我从事于视觉设计行业,创造屡获殊荣,电影和电视节目等高端3D效果,例如 Tron, The Thing, Resident Evil,和 Vikings .为了能够创造这些 ...
最新文章
- 企业级 SpringBoot 教程 (十九) 验证表单信息
- NumPy和Pandas常用库
- java线程池饱和策略_线程池的饱和策略-调用者执行 | 学步园
- Spark-SQL从MySQL中加载数据以及将数据写入到mysql中(Spark Shell方式,Spark SQL程序)
- SSL/TLS协议运行机制
- 【原创】ABAP动态编程之功能实现
- 罗永浩宣布要做带货一哥后,合作单子如雪花般飞来
- gitlab php自动化测试,自动化发布-GitLab WEB Hooks 配置
- /proc 文件系统并使用/proc 进行输入
- 3389远程连接问题的一个解决办法
- vue-cli解决兼容ie的es6+api问题
- Java多线程间的数据共享
- 评分预测会不会大于满分5.0的情况?
- 拷贝网页内容增加版权信息的 JavaScript 代码示例
- Ubuntu 11.10 系统启动默认进入终端
- 【ENVI解决经验】裁剪后背景改为白色(透明)
- flow.php 漏洞,php – 使用Apache的Flowplayer安全流
- html菜单栏向左展开与收起,网页左侧固定菜单栏的展开与收起
- Js数据类型间的相互转换
- 《最后的教父》小说人物一览表