其实这里的通知和之前说到的KVO功能很想,也是用于监听操作的,但是和KVO不同的是,KVO只用来监听属性值的变化,这个发送监听的操作是系统控制的,我们控制不了,我们只能控制监听操作,类似于Android中系统发送的广播,我们只能接受。但是通知就不一样了,他的监听发送也是又我们自己控制,我们可以在任何地方任何时机发送一个通知,类似于Android中开发者自己发送的广播。从这一点看来,通知的使用场景更为广泛了。

下面就来看一下例子:

还是护士和小孩的那个例子

Children.h

  1. //
  2. //  Children.h
  3. //  44_KVO
  4. //
  5. //  Created by jiangwei on 14-10-16.
  6. //  Copyright (c) 2014年 jiangwei. All rights reserved.
  7. //
  8. #import <Foundation/Foundation.h>
  9. @interface Children : NSObject
  10. @property NSInteger *hapyValue;
  11. @end

定义了一个属性:hapyValue

Children.m

  1. //
  2. //  Children.m
  3. //  44_KVO
  4. //
  5. //  Created by jiangwei on 14-10-16.
  6. //  Copyright (c) 2014年 jiangwei. All rights reserved.
  7. //
  8. #import "Children.h"
  9. @implementation Children
  10. - (id) init{
  11. self = [super init];
  12. if(self != nil){
  13. //启动定时器
  14. [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
  15. self.hapyValue= 100;
  16. }
  17. return self;
  18. }
  19. - (void) timerAction:(NSTimer *) timer{
  20. //使用set方法修改属性值,才能触发KVO
  21. _hapyValue--;
  22. NSLog(@"%@",_hapyValue);
  23. if(_hapyValue <80){
  24. //发送通知
  25. //这里和KVO的区别,我们可以手动的发送通知
  26. //注意通知的名称,传递的参数必须和定义通知的地方的参数值要一致
  27. //将Children对象传递过去
  28. [[NSNotificationCenter defaultCenter] postNotificationName:@"happyValueNotification" object:self];
  29. }
  30. }
  31. @end

定义了一个定时器,但是我们看到这里的timerAction方法中就开始发送一个通知了:

  1. //发送通知
  2. //这里和KVO的区别,我们可以手动的发送通知
  3. //注意通知的名称,传递的参数必须和定义通知的地方的参数值要一致
  4. //将Children对象传递过去
  5. [[NSNotificationCenter defaultCenter] postNotificationName:@"happyValueNotification" object:self];

我们在属性值发生变化的地方发送一个通知:NSNotificationCenter

第一个参数:通知的名称,这个名称必须和后面接受通知的名称一致

第二个参数:可以传递的一个参数对象

Nure.h

  1. //
  2. //  Nure.h
  3. //  44_KVO
  4. //
  5. //  Created by jiangwei on 14-10-16.
  6. //  Copyright (c) 2014年 jiangwei. All rights reserved.
  7. //
  8. #import <Foundation/Foundation.h>
  9. @interface Nure : NSObject
  10. @end

Nure.m

  1. //
  2. //  Nure.m
  3. //  44_KVO
  4. //
  5. //  Created by jiangwei on 14-10-16.
  6. //  Copyright (c) 2014年 jiangwei. All rights reserved.
  7. //
  8. #import "Nure.h"
  9. #import "Children.h"
  10. @implementation Nure
  11. - (id) init{
  12. self = [super init];
  13. if(self != nil){
  14. //监听一个通知,当收到通知时,调用notificationAction方法
  15. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationAction) name:@"happyValueNotification" object:nil];
  16. }
  17. return self;
  18. }
  19. - (void) notificationAction:(NSNotification *)notification{
  20. //这里我们拿到Children对象进行操作
  21. Children *children = notification.object;
  22. NSLog(@"触发通知");
  23. }
  24. - (void)dealloc{
  25. //移除指定的通知,不然会造成内存泄露
  26. [[NSNotificationCenter defaultCenter] removeObserver:self name:@"happyValueNotification" object:nil];
  27. //Children对象可以添加多个通知
  28. //下面的方法是可以移除Children中所有通知
  29. [[NSNotificationCenter defaultCenter] removeObserver:self];
  30. }
  31. @end

在Nure类中我们开始接受通知了:

  1. //监听一个通知,当收到通知时,调用notificationAction方法
  2. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationAction) name:@"happyValueNotification" object:nil];

使用addObserver方法来监听通知

第一个参数:监听者对象

第二个参数:监听处理逻辑的方法

第三个参数:通知的名称

第四个参数:通知发送的时候传递过来的参数对象

1、处理通知的方法

  1. - (void) notificationAction:(NSNotification *)notification{
  2. //这里我们拿到Children对象进行操作
  3. Children *children = notification.object;
  4. NSLog(@"触发通知");
  5. }


里会传递一个NSNotification对象,通过object属性可以获取到监听对象了,因为我们在发送通知的时候传递过来的这个对象。那么这里我们
就可以获取监听对象的属性值了,但是这里我们如果想知道属性值变化前和变化后的值,我们可以在Children类中在定义一个属性专门用来记录旧的属性
值,这样就可以了。

2、销毁方法

  1. - (void)dealloc{
  2. //移除指定的通知,不然会造成内存泄露
  3. [[NSNotificationCenter defaultCenter] removeObserver:self name:@"happyValueNotification" object:nil];
  4. [[NSNotificationCenter defaultCenter] removeObserver:self];
  5. }

在销毁的方法中,我们可以需要移除监听者,传递过去通知名

但是这里我们会注意到,还有一个方法:removeObserver方法,是用来移除所有监听者的,因为可能有多个监听者。

总结

OC中KVO操作和通知都是很重要的一个操作,他们的原理是基于观察者模式的,但是KVO操作没有通知灵活。但是KVO也有自己的优点,比如可以记录新旧值,这个通知就比较麻烦点了,所以我们在使用的时候视情况而定,一般监听属性值变化的我们还是使用KVO.

使用过程中需要注意的几点事项:

一、了解几个相关的类

1、NSNotification

这个类可以理解为一个消息对象,其中有三个成员变量。

这个成员变量是这个消息对象的唯一标识,用于辨别消息对象。

@property (readonly, copy) NSString *name;

这个成员变量定义一个对象,可以理解为针对某一个对象的消息。

@property (readonly, retain) id object;

这个成员变量是一个字典,可以用其来进行传值。

@property (readonly, copy) NSDictionary *userInfo;

NSNotification的初始化方法:

- (instancetype)initWithName:(NSString *)name object:(id)object userInfo:(NSDictionary *)userInfo;

+ (instancetype)notificationWithName:(NSString *)aName object:(id)anObject;

+ (instancetype)notificationWithName:(NSString *)aName object:(id)anObject userInfo:(NSDictionary *)aUserInfo;

注意:官方文档有明确的说明,不可以使用init进行初始化

2、NSNotificationCenter

这个类是一个通知中心,使用单例设计,每个应用程序都会有一个默认的通知中心。用于调度通知的发送的接受。

添加一个观察者,可以为它指定一个方法,名字和对象。接受到通知时,执行方法。

- (void)addObserver:(id)observer selector:(SEL)aSelector name:(NSString *)aName object:(id)anObject;

发送通知消息的方法

- (void)postNotification:(NSNotification *)notification;

- (void)postNotificationName:(NSString *)aName object:(id)anObject;

- (void)postNotificationName:(NSString *)aName object:(id)anObject userInfo:(NSDictionary *)aUserInfo;

移除观察者的方法

- (void)removeObserver:(id)observer;

- (void)removeObserver:(id)observer name:(NSString *)aName object:(id)anObject;

二、通知的使用流程

首先,我们在需要接收通知的地方注册观察者,比如:

    //获取通知中心单例对象
    NSNotificationCenter * center = [NSNotificationCenter defaultCenter];
    //添加当前类对象为一个观察者,name和object设置为nil,表示接收一切通知
    [center addObserver:self selector:@selector(notice:) name:@"123" object:nil];

之后,在我们需要时发送通知消息

    //创建一个消息对象
    NSNotification * notice = [NSNotification notificationWithName:@"123" object:nil userInfo:@{@"1":@"123"}];
    //发送消息
       [[NSNotificationCenter defaultCenter]postNotification:notice];

我们可以在回调的函数中取到userInfo内容,如下:

-(void)notice:(id)sender{
    NSLog(@"%@",sender);
}

三、多线程通知

首先看下苹果的官方说明:

Regular notification centers deliver notifications on the thread in which the notification was posted. Distributed notification centers deliver notifications on the main thread. At times, you may require notifications to be delivered on a particular thread that is determined by you instead of the notification center. For example, if an object running in a background thread is listening for notifications from the user interface, such as a window closing, you would like to receive the notifications in the background thread instead of the main thread. In these cases, you must capture the notifications as they are delivered on the default thread and redirect them to the appropriate thread.

意思很简单,NSNotificationCenter消息的接受线程是基于发送消息的线程的。也就是同步的,因此,有时候,你发送的消息可能不在主线程,而大家都知道操作UI必须在主线程,不然会出现不响应的情况。所以,在你收到消息通知的时候,注意选择你要执行的线程。下面看个示例代码

//接受消息通知的回调
- (void)test
{
if ([[NSThread currentThread] isMainThread]) {
NSLog(@"main");
} else {
NSLog(@"not main");
}
dispatch_async(dispatch_get_main_queue(), ^{
//do your UI
}); } //发送消息的线程
- (void)sendNotification
{
dispatch_queue_t defaultQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(defaultQueue, ^{
[[NSNotificationCenter defaultCenter] postNotificationName:@"test" object:nil];
});
}

 
												

iOS之NSNotificationCenter通知中心使用事项的更多相关文章

  1. iOS 设计模式-NSNotificationCenter 通知中心

    通知介绍 每一个应用程序都有一个通知中心(NSNotificationCenter)实例,专门负责协助不同对象之间的消息通信 任何一个对象都可以向通知中心发布通知(NSNotification),描述 ...

  2. NSNotificationCenter通知中心

    概述 NSNotificationCenter通知中心,通常用于一对一或者一对多的消息传递,即当一个地方改变时,要求改变其他的一些地方,例如当网络请求回来了新的数据,需要刷新本地信息和本地内存里面的界 ...

  3. iOS开发之通知中心(NSNotificationCenter)

    前言 面向对象的设计思想是把行为方法封装到每一个对象中,以用来增加代码的复用性.正是这种分散封装,增加了对象之间的相互关联,总是有很多的对象需要彼此了解以及相互操作! 一个简单示例说明这种交互产生的对 ...

  4. iOS生命周期 & 通知中心

    笔记内容 学习笔记-段玉磊 Stanford course View Controller Lifecycle 这篇文是我记载Developing iOS 7 Apps公开课 第5课的笔记 UITex ...

  5. IOS NSNotification Center 通知中心的使用

    通知中心,它是IOS程序内部的一种消息广播机制,通过它,可以实现无引用关系的对象之间的通信.通知中心他是基于观察者模式,它只能进行程序内部通信,不能跨应用程序进程通信.当通知中心接受到消息后会根据设置 ...

  6. NSNotificationCenter 通知中心传值

    1.NSNotification 这个类可以理解为一个消息对象,其中有三个成员变量. 这个成员变量是这个消息对象的唯一标识,用于辨别消息对象. @property (readonly, copy) N ...

  7. iOS 通知中心 NSNotificationCenter

    iOS开发中,每个app都有一个通知中心,通知中心可以发送和接收通知. 在使用通知中心 NSNotificationCenter之前,先了解一下通知 NSNotification. NSNotific ...

  8. 通知中心 NSNotificationCenter 的简单使用方法

    NSNotificationCenter(通知中心)   [注意]需再dealloc中移除观察者   获取通知中心单例对象 NSNotificationCenter *center=[NSNotifi ...

  9. 通知中心 NSNotificationCenter

    NSNotificationCenter 通知中心提供了一种在程序内广播信息的途径,一个NSNotificationCenter对象本质上是一个通知分发表(notification dispatch ...

随机推荐

  1. Form.KeyPreview 属性2

    在使用.Net Framework编写窗体应用程序的时候,有时有需要响应窗体的按键消息. 当窗体上没有任何其他控件的时候,窗体是可以直接响应这些消息的. 但是当窗体上有其他控件时,会发现窗体再也不会响 ...

  2. URI Scheme

    1. 什么是URI Scheme? 一般情况下,遇到这种概念不清的问题,最好的第一手资料就是wiki,实在看不懂,再看百度百科,但前者给出的资料一般都是更加准确一些. 以下为维基百科和百度百科关于这个 ...

  3. $destroy

    ng-view 路由切换会触发 $destroy

  4. [转]ASP.NET MVC 入门1、简介

    什么是MVC模式 MVC(Model-View-Controller,模型—视图—控制器模式)用于表示一种软件架构模式.它把软件系统分为三个基本部分:模型(Model),视图(View)和控制器(Co ...

  5. C# 隐藏和覆盖

    1.在C#里面,只有声明vitual.abstract和带override的方法能够被子类重写(override). 2.如果父类方法没有以上关键字,子类又有和父类一样的方法,那么,就默认隐藏父类方法 ...

  6. Farewell, 2015, welcome 2016

    Farewell, 2015, welcome 2016.   ##事出必有因 从2014年10月份开始, 在投资的路上越走越远.  盲目的行为, 付出了惨重的代价. 投资无所谓对错, 但投资失败带来 ...

  7. 【CSS】Intermediate2:Pseudo Classes

    1.specify a state or relation to the selector selector:pseudo_class { property: value; } 2.Link 3.Dy ...

  8. bzoj 1922 [Sdoi2010]大陆争霸(最短路变形)

    Description 在一个遥远的世界里有两个国家:位于大陆西端的杰森国和位于大陆东端的 克里斯国.两个国家的人民分别信仰两个对立的神:杰森国信仰象征黑暗和毁灭 的神曾·布拉泽,而克里斯国信仰象征光 ...

  9. Centos System Info

    系统 # uname -a # 查看内核/操作系统/CPU信息 # head -n 1 /etc/issue # 查看操作系统版本 # cat /proc/cpuinfo # 查看CPU信息 # ho ...

  10. PC-计算机动行命令里的密密!系统管理程序!

    1. gpedit.msc-----组策略 ­ 3. Nslookup-------IP地址侦测器 ­ 4. explorer-------打开资源管理器 ­ 5. logoff---------注销 ...