1.什么是NSNotification

每个运行中的application都有一个NSNotificationCenter的成员变量,它的功能就类似与公共栏,对象在这里注册关注每个确定Notification,我们把这些注册对象叫做observer,其他的一些对象会给center发送Notification,center将该notification转发

所有注册对该notification感兴趣的对象,我们把这些发送Notification的对象叫做poster。

很多的标准cocoa类会发送Notification,在改变Size的时候,windows会发送Notification;选择tableview中的一行时,tableview会发送Notification;我们可以在帮助文档中查看标准cocoa对象发送的Notification。

[Notification就是设计模式中的观察者模式, cocoa为我们实现了该模式, 就像Java也有同样的实现一样]。

2.创建一个通知对象:使用notificationWithName:object: 或者 notificationWithName:object:userInfo:

NSNotification* notification = [NSNotification notificationWithName:kImageNotificationLoadFailed(connection.imageURL)
                                                                 object:self
                                                               userInfo:[NSDictionary dictionaryWithObjectsAndKeys:error,@"error",connection.imageURL,@"imageURL",nil]];

这里需要注意的是,创建自己的通知并不是必须的。而是在创建自己的通知之前,采用NSNotificationCenter类的方法 postNotificationName:object: 和 postNotificationName:object:userInfo:更加便利的发出通知。这种情况,一般使用NSNotificationCenter的类方法defaultCenter就获得默认的通知对象,这样你就可以给该程序的默认通知中心发送通知了。注意:每一个程序都有一个自己的通知中心,即NSNotificationCenter对象。该对象采用单例设计模式,采用defaultCenter方法就可以获得唯一的NSNotificationCenter对象。

注意:NSNotification对象是不可变的,因为一旦创建,对象是不能更改的。

3.注册通知:addObserver:selector:name:object:

可以看到除了添加观察者之外,还有其接收到通知之后的执行方法入口,即selector的实参。因此为了进行防御式编程,最好先检查观察者是否定义了该方法。例如:添加观察者代码有

[[NSNotificationCenter defaultCenter] addObserver:self
    selector:@selector(aWindowBecameMain:)
    name:NSWindowDidBecomeMainNotification object:nil];

这里保证了self定义了aWindowBecameMain:方法。而对于一个任意的观察者observer,不能保证其对应的selector有aWindowBecameMain:,可采用[observer respondsToSelector:@selector(aWindowBecameMain:)]] 进行检查。所以完整的添加观察者过程为:

if([observer respondsToSelector:@selector(aWindowBecameMain:)]) {
        [[NSNotificationCenter defaultCenter] addObserver:observer selector:@selector(aWindowBecameMain:) name:NSWindowDidBecomeMainNotification object:nil];
    }

注意到addObserver:selector:name:object:不仅指定一个观察者,指定通知中心发送给观察者的消息,还有接收通知的名字,以及指定的对象。一般来说不需要指定name和object,但如果仅仅指定了一个object,观察者将收到该对象的所有通知。例如将上面的代码中name改为nil,那么观察者将接收到object对象的所有消息,但是确定不了接收这些消息的顺序。如果指指定一个通知名称,观察者将收到它每次发出的通知。例如,上面的代码中object为nil,那么客户对象(self)将收到任何对象发出NSWindowDidBecomeMainNotification通知。如果既没有指定指定object,也没有指定name,那么该观察者将收到所有对象的所有消息。

4.发送通知:postNotificationName:object:或者performSelectorOnMainThread:withObject:waitUntilDone:

例如程序可以实现将一个文本可以进行一系列的转换,例如对于一个实例、RTF格式转换成ASCII格式。而转换在一个类(如Converter类)的对象中得到处理,在诚寻执行过程中可以加入或者删除这种转换。而且当添加或者删除Converter操作时,你的程序可能需要通知其他的对象,但是这些Converter对象并不需要知道被通知对象是什么,能干什么。你只需要声明两个通知,"ConverterAdded" 和 "ConverterRemoved",并且在某一事件发生时就发出这两个通知。

当一个用户安装或者删除一个Converter,它将发送下面的消息给通知中心:

[[NSNotificationCenter defaultCenter]
    postNotificationName:@"ConverterAdded" object:self];

或者是

[[NSNotificationCenter defaultCenter]
    postNotificationName:@"ConverterRemoved" object:self];

通知中心将会区分它们对象对这些通知感兴趣并且通知他们。如果除了关心观察者的通知名称和观察的对象,还关心其他之外的对象,那么就把之外的对象放在通知的可选字典中,或者用方法postNotificationName:object:userInfo:。

而采用performSelectorOnMainThread:withObject:waitUntilDone:则是直接调用NSNotification的方法postNotification,而postNotificationName和object参数可以放到withObject的实参中。例如:

[[NSNotificationCenter defaultCenter] performSelectorOnMainThread:@selector(postNotification:) withObject:notification waitUntilDone:YES];//注意这里的notification为自定义的一个通知对象,可定义为NSNotification* notification = [NSNotification notificationWithName:@"ConverterAdded"object:self];//那么它的作用与上面的一致

5.移除通知:removeObserver:和removeObserver:name:object:

其中,removeObserver:是删除通知中心保存的调度表一个观察者的所有入口,而removeObserver:name:object:是删除匹配了通知中心保存的调度表中观察者的一个入口。

这个比较简单,直接调用该方法就行。例如:

[[NSNotificationCenter defaultCenter] removeObserver:observer name:nil object:self];

注意参数notificationObserver为要删除的观察者,一定不能置为nil。

NSNotification的更多相关文章

  1. iOS---正确使用NSNotification对象

    我们在开发程序的时候,程序内不同对象间的通信是不可避免的,iOS中主要有以下这些通信方式: iOS中的通信方式 图中按照耦合度的强弱和通信的形式(一对一还是一对多)进行了划分,这篇文章我们主要说一下N ...

  2. 04 KVC|KVO|Delegate|NSNotification区别

    一. iOS 中KVC.KVO.NSNotification.delegate 在实际的编程中运用的非常多,掌握好他们的运行原理和使用场合对于我们程序的开发将会带来事办工倍的效果:   二. KVC ...

  3. NSNotification --关于通知

    一. 通知(NSNotification)的发送(Post)和注册(add)都必须借助于通知中心(NSNotificationCenter) 发送通知: NSNotificationCenter *c ...

  4. (ios) nsnotification总结

    1  文本输入,键盘显示时,view向上,键盘隐藏时,view向下 1.1 注册键盘显示,关闭通知,并实现主界面上下变动 [[NSNotificationCenter defaultCenter] a ...

  5. KVC、KVO、NSNotification、delegate 总结及区别

    1.KVC,即是指 NSKeyValueCoding,一个非正式的Protocol,提供一种机制来间接访问对象的属性.而不是通过调用Setter.Getter方法访问.KVO 就是基于 KVC 实现的 ...

  6. ios基础篇(十八)——Delegate 、NSNotification 和 KVO用法及其区别

    一.Delegate Delegate本质是一种程序设计模型,iOS中使用Delegate主要用于两个页面之间的数据传递.iphone中常用@protocol和delegate的机制来实现接口的功能. ...

  7. iOS NSNotification的使用

    如果在一个类中想要执行另一个类中的方法可以使用通知 1.创建一个通知对象:使用notificationWithName:object: 或者 notificationWithName:object:u ...

  8. ios delegate, block, NSNotification用法

    ios中实现callback可以通过两种方法,委托和NSNotification 委托的话是一对一的关系,例如一个UIViewController里有一个tableView, 将该viewContro ...

  9. NSNotification Name 最佳写法

    本文主要借探讨NSNotificationName的最佳写法的机会,学习下extern, static, const, #define 和常量指针与指针常量等的特性和用法. 1.NSNotificat ...

  10. NSNotification系统通知优化

    最近在github上看到了LRNotificationObserver这个项目,看了一下实现方式,作者通过ARC机制实例化注册对象子类与关联对象的方法来管理注册对象的生命周期.从而省去了系统通知移除的 ...

随机推荐

  1. Fastify 系列教程二 (中间件、钩子函数和装饰器)

    Fastify 系列教程: Fastify 系列教程一 (路由和日志) Fastify 系列教程二 (中间件.钩子函数和装饰器) 中间件 Fastify 提供了与 Express 和 Restify ...

  2. phalcon——闪存消息

    使用两种适配器来定义消息传递给Flasher后的行为: (1)Phalcon\Flash\Direct:直接输出传递给flasher的消息 (2)Phalcon\Flash\Session:将消息临时 ...

  3. 更新Android Studio 3.0碰到的问题

    更新完后试下运行正在维护的旧项目,出现各种错误,因为后来发现问题不在这,所以没记完整,大概如下: A larger heap for the Gradle daemon is recommended ...

  4. seajs源码

    /*** Sea.js 3.0.0 | seajs.org/LICENSE.md 中文注释由 李祥威 添加,为个人对细节的理解,官方解释很详细的地方就不说了 难免有错漏,联系我: chuangweil ...

  5. Android打开/data/目录以及导出文件

    打开logcat和和file Explorer Tools-->Android-->Android Device Monitor 如果右侧没有出现,Windows-->Show Vi ...

  6. CSS3 动画 animation和@keyframes

    CSS3 @keyframes 规则 如需在 CSS3 中创建动画,您需要学习 @keyframes 规则. @keyframes 规则用于创建动画.在 @keyframes 中规定某项 CSS 样式 ...

  7. ldap数据库--ODSEE--复制协议

    简单介绍一下ODSEE的复制拓扑的建立,复制协议可以通过管理界面进行创建,也可以通过命令行创建.在此之前需要了解一些复制协议的相关概念,这里针对OESEE. 1,复制角色 master(提供者,也可以 ...

  8. 关于java数据库章节connection连接不成功的时候!!!

    无图,因为忘了截图.但是网上很多说法: 异常那个地方最先是说连接失败的,原因很简单,没有安装Mysql数据库!!!安装了之后出示没有密码,所以程序里面的地方也不要有密码. 然后运行就成功了.相关的安装 ...

  9. 全新的.NET解释器 - Mono已经到来

    Mono通过新的运行代码方式,完善了自己的即时编译器和静态编译器. 2001年,Mono项目正式开始,Mono开发团队为.NET指令集编写了一个解释器,用于在Linux上引导一个自托管的.NET开发环 ...

  10. C#内部关于绑定事件Event的线程安全

    private EventHandler _FieldsChanged;public event EventHandler FieldsChanged{    add    {        Even ...