通常我们在 iOS 中发生什么事件时该做什么是由 Delegate 实现的,例如 View 加载完后会触发 viewDidLoad。Apple 还为我们提供了另一种通知响应方式,那就是 NSNotification,系统中(UIKeyboardDidShowNotification 等) 以及某些第三方组件(例如 ASIHTTPRequest 的 kReachabilityChangedNotification 等)。

NSNotificationCenter 较之于 Delegate 可以实现更大的跨度的通信机制,可以为两个无引用关系的两个对象进行通信。NSNotificationCenter 的通信原理使用了观察者模式:

1. NSNotificationCenter 注册观察者对某个事件(以字符串命名)感兴趣,及该事件触发时该执行的 Selector 或 Block
2. NSNotificationCenter 在某个时机激发事件(以字符串命名)
3. 观察者在收到感兴趣的事件时,执行相应的 Selector 或 Block

使用 NSNotificationCenter 的步骤示例代码:

1. 定义一个事件到来时该执行的方法:

 - (void)execute:(NSNotification *)notification {
//do something when received notification
//notification.name is @"NOTIFICATION_NAME"
if(notification.object && [notification.object isKindOfClass:[Test class]]){
//do something
}
}

2. 注册观察者:

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

使用默认的通知中心,上面代码的意义的,观察者 self   在收到名为 @"NOTIFICATION_NAME" 的事件是执行 @selector(execute:),最后一个参数是表示会对哪个发送者对象发出的事件作出响应,nil 时表示接受所有发送者的事件。

还有一种注册观察者的方式是用方法:

- (id)addObserverForName:(NSString *)name object:(id)obj queue:(NSOperationQueue *)queue usingBlock:(void (^)(NSNotification *))block

3. 激发事件,即通知相应的观察者

[[NSNotificationCenter defaultCenter] postNotificationName:@"NOTIFICATION_NAME"
object:nil];
//或者用下面几行代码,明确的 notification 示例
Test *test = [[Test alloc] init];
NSNotification *notification = [NSNotification notificationWithName:@"NOTIFICATION_NAME" object:test];
[[NSNotificationCenter defaultCenter] postNotification:notification];

这里的 object 参数对应到方法 - (void)execute:(NSNotification *)notification 里的 notification.object, name 就是 notification.name。

代码到这里,方法 - (void)execute:(NSNotification *)notification 就会得到执行了。

说明:我们上面用的  [NSNotificationCenter defaultCenter] 同一个实例,你也可以使用自己的 NSNotificationCenter,如:

NSNotificationCenter *notificationCenter = [[NSNotificationCenter alloc]init];

事件只会在当前的 NotificationCenter 中广播,不同的 NotificationCenter 之间的事件通知互不相干。

NSNotificationCenter 比之 Delegate 的好处就是事件发出者与响应者可以完全不认识,例如你在某个类中注册了 A 观察者某 E 事件的响应,你可以在程序的任何代码 X 中激发 E,A 的相应选择器即被触发,对象 A 与 X 完全是松散的。

4. 你的观察者如果对一些事件没兴趣了,应该从 NotificationCenter 中移除掉:

[[NSNotificationCenter defaultCenter] removeObserver:self name:@"NOTIFICATION_NAME"
object:test];//object 与注册时相同
//或[[NSNotificationCenter defaultCenter] removeObserver:self];

系统里定义了许多的 XxxNotification 名称,其实只要 Cmd+Shift+O 打开 Open Quickly,输入 nsnotification 或者 uinotification 可以看到许多以 Notification 结尾的变量定义,由变量名称也能理解在什么时候会激发什么事件,一般都是向 [NSNotificationCenter defaultCenter] 通知的。

比如你想对系统的某些事件时作出响应只要注册一个观察者即可,想要在每次键盘显示后得到通知就得关心 UIKeyboardDidShowNotification 事件:

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardDidShow:)
name:UIKeyboardDidShowNotification
object:nil];

键盘显示后就会执行 self 的 keyboardDidShow 方法。

我们可以多看看第三方 Objective-C 库是怎么运用的 NSNotificationCenter。

原文转载自:http://www.cnblogs.com/wenxp2006/articles/2499330.html

NSNotificationCenter 的使用详解的更多相关文章

  1. NSNotificationCenter 使用姿势详解

    来源:JamesYu 链接:http://www.jianshu.com/p/a4d519e4e0d5 最近在做平板的过程中,发现了一些很不规范的代码.偶然修复支付bug的时候,看到其他项目代码,使用 ...

  2. iOS NSNotificationCenter 使用姿势详解

    最近在做平板的过程中,发现了一些很不规范的代码.偶然修复支付bug的时候,看到其他项目代码,使用通知的地方没有移除,我以为我这个模块的支付闪退是因为他通知没有移除的缘故.而在debug和看了具体的代码 ...

  3. iOS开发——实用技术OC篇&事件处理详解

    事件处理详解 一:事件处理 事件处理常见属性: 事件类型 @property(nonatomic,readonly) UIEventType     type; @property(nonatomic ...

  4. iOS中MVC等设计模式详解

    iOS中MVC等设计模式详解 在iOS编程,利用设计模式可以大大提高你的开发效率,虽然在编写代码之初你需要花费较大时间把各种业务逻辑封装起来.(事实证明这是值得的!) 模型-视图-控制器(MVC)设计 ...

  5. 《招一个靠谱的移动开发》iOS面试题及详解(下篇)

    iOS面试知识点 现在进入本篇的正题.本篇的面试题是我认为比较好的iOS开发基础知识点,希望大家看过这后在理解的基础上掌握而不是死记硬背.死记硬背很快也会忘记的. 1 iOS基础 1.1 父类实现深拷 ...

  6. 《招一个靠谱的移动开发》iOS面试题及详解(上篇)

    以下问题主要用于技术的总结与回顾 主要问题总结 单例的写法.在单利中创建数组应该注意些什么. NSString 的时候用copy和strong的区别. 多线程.特别是NSOperation 和 GCD ...

  7. Linq之旅:Linq入门详解(Linq to Objects)

    示例代码下载:Linq之旅:Linq入门详解(Linq to Objects) 本博文详细介绍 .NET 3.5 中引入的重要功能:Language Integrated Query(LINQ,语言集 ...

  8. 架构设计:远程调用服务架构设计及zookeeper技术详解(下篇)

    一.下篇开头的废话 终于开写下篇了,这也是我写远程调用框架的第三篇文章,前两篇都被博客园作为[编辑推荐]的文章,很兴奋哦,嘿嘿~~~~,本人是个很臭美的人,一定得要截图为证: 今天是2014年的第一天 ...

  9. EntityFramework Core 1.1 Add、Attach、Update、Remove方法如何高效使用详解

    前言 我比较喜欢安静,大概和我喜欢研究和琢磨技术原因相关吧,刚好到了元旦节,这几天可以好好学习下EF Core,同时在项目当中用到EF Core,借此机会给予比较深入的理解,这里我们只讲解和EF 6. ...

随机推荐

  1. 【Codeforces 1030D】Vasya and Triangle

    [链接] 我是链接,点我呀:) [题意] 题意 [题解] 参考这篇题解:https://blog.csdn.net/mitsuha_/article/details/82825862 为什么可以保证m ...

  2. Java中list集合ArrayList 中contains包含的使用

    Java中list集合ArrayList 中contains包含的使用 https://blog.csdn.net/qq_38556611/article/details/78774690

  3. nyoj 113 字符串替换 (string中替换函数replace()和查找函数find())

    字符串替换 时间限制:3000 ms  |  内存限制:65535 KB 难度:2   描述 编写一个程序实现将字符串中的所有"you"替换成"we"   输入 ...

  4. node.js 利用流实现读写同步,边读边写

    //10个数 10个字节,每次读4b,写1b let fs=require("fs"); function pipe(source,target) { //先创建可读流,再创建可写 ...

  5. kendo Cannot read property 'call' of undefined

    造成这个错误的原因是在 必须有id的定义

  6. BZOJ(7) 1085: [SCOI2005]骑士精神

    1085: [SCOI2005]骑士精神 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3233  Solved: 1911[Submit][Stat ...

  7. ISATAP隧道方式接入IPv6和RRAS(Windows路由与远程访问)似乎是冲突的

    在启用了RRAS的NAT服务器上设置ISATAP隧道,虽然能正常获取IPv6地址,但是IPv6网络实际是不通的...

  8. mybatis中的map.xml文件中sql语句需要分号吗?

    mybatis中的map.xml文件中sql语句需要分号吗? :你是说sql介绍的分号吗?不需要的

  9. 使用CDN

    CDN的全称是Content Delivery Network.中文直译过来是:内容交付网络. 它的主要意思是,将某些内容进行交付的网络.对于站点开发而言,我们所讲的内容通常指的是内容文件(比如jav ...

  10. iOS 打开扬声器以及插入耳机的操作

    废话不多说说一下现状 网上好多关于扬声器的操作,可是问题多多.SDK7.X 和SDK7.X以上版本号有点诧异 #import <Foundation/Foundation.h> #impo ...