通知NSNotification和KVO的使用

1.通知NSNotification的使用
NSNotification的名称在整个项目中必须是唯一的
补充一个小知识,为了确保通知名称的唯一性,定义NSNotification的name时需要做些改变
前边定义时如下

#define AnyNotificationName   @"notiName"

最好写成

1 NSString * const AnyNotificationName = @"notiName";
2 //也可写成下面的方式,这是等价的。可以通过打印内存地址来比较
3 const NSString *AnyNotificationName = @"notiName";

因为#define本质上还是NSString *,它与NSString * const的区别在于NSString *的指针可以改变指向(虽然内容不会改变),而NSString * const就是指向、内容都无法改变,更安全。因此在定义一些全局唯一性的属性时,推荐该法。

①使前用先注册监听者,在下例中,当有名字为AnyNotificationName的通知发送到通知中心NSNotificationCenter后,就执行centerActive方法

 1 NSString * const AnyNotificationName = @"notiName";
 2
 3 /**
 4 * 在通知中心(NSNotificationCenter)中注册监听者
 5 *
 6 * 通知中心(NSNotificationCenter)中注册观察者
 7 * addObserver 注册的观察者
 8 *
 9 * selector 收到通知后执行的方法
10 * name     通知的名字,也是通知的唯一标识
11 * object   这里的object不是传递给监听者的数据,通常为nil
12 */
13 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(centerActive:) name:AnyNotificationName object:nil];

②使用完毕后要从NSNotificationCenter移除观察者

[[NSNotificationCenter defaultCenter] removeObserver:self name:AnyNotificationName object:nil];
1 ///接收通知中心发送的通知后执行的方法
2 -(void)centerActive:(NSNotification *) notification{
3     if ([notification.name isEqualToString:AnyNotificationName]) {
4         NSLog(@"通知中心发送的通知名称为:%@",notification.name);
5     }
6 }

③触发通知,在调用通知的时候会在整个项目中寻找符合该名称的通知,所以通知的name必须唯一

1 NSArray *aaa = @[@"me",@"you",@"him"];
2 //发送一个名为AnyNotificationName(notiName)的通知给观察者,这里的object才是传递给监听者的数据
3 [[NSNotificationCenter defaultCenter] postNotificationName:AnyNotificationName object:aaa];

下面是完整的例子

 1 NSString * const AnyNotificationName = @"notiName";
 2
 3 @interface ViewController ()
 4
 5 @end
 6
 7 @implementation ViewController
 8
 9 - (void)viewDidLoad {
10     [super viewDidLoad];
11
12     UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
13     [btn setTitle:@"发送通知" forState:UIControlStateNormal];
14     [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
15     btn.frame = CGRectMake(100, 300, 100, 50);
16     [btn addTarget:self action:@selector(sendNotification) forControlEvents:UIControlEventTouchUpInside];
17     [self.view addSubview:btn];
18
19 }
20
21 /**
22  * 通知中心(NSNotificationCenter)中注册观察者
23  * addObserver 注册的观察者
24  *
25  * selector 收到通知后执行的方法
26  * name     通知的名字,也是通知的唯一标识
27  * object   这里不是传递给观察者的参数,通常为nil。
28  */
29 - (void)viewDidAppear:(BOOL)animated{
30     [super viewDidAppear:animated];
31
32     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(centerActive:) name:AnyNotificationName object:nil];
33 }
34
35 ///从通知中心(NSNotificationCenter)移除观察者
36 -(void)viewDidDisappear:(BOOL)animated{
37     [super viewDidDisappear:animated];
38
39     [[NSNotificationCenter defaultCenter] removeObserver:self name:AnyNotificationName object:nil];
40 }
41
42 ///接收通知中心发送的通知
43 -(void)centerActive:(NSNotification *) notification{
44     if ([notification.name isEqualToString:AnyNotificationName]) {
45         NSArray *a = notification.object;
46         NSLog(@"通知中心发送的通知名称为:%@,数组为=%@",notification.name,a);
47     }
48 }
49
50 ///利用通知中心发送通知,同时传递数据
51 -(void)sendNotification{
52     NSArray *aaa = @[@"me",@"you",@"him"];
53     //发送一个名为AnyNotificationName(notiName)的通知给观察者
54     [[NSNotificationCenter defaultCenter] postNotificationName:AnyNotificationName object:aaa];
55 }
56
57 @end

2.知道了NSNotification,下面介绍下KVO,也是用的观察者模式,包括注册观察者、注销观察者等。如下:
定义两个类,被观察者和观察者

1 /** 被观察者,定义一个被观察的属性 */
2 @interface KVOSubject : NSObject
3 @property(nonatomic,copy) NSString *changedStr;
4 @end
5
6 /** 观察者 */
7 @interface KVObserver : NSObject
8 @end

在观察者KVObserve的.m中实现一个方法,这个方法主要是用来当被观察的值发生改变时进行的操作

1 -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
2     //获取属性改变后的新值
3     NSString *aaa = change[NSKeyValueChangeNewKey];
4     NSLog(@"值发生了改变");
5 }

然后就可以进行观察行为

 1 -(void)activeKVO{
 2     KVOSubject *kvoSub = [[KVOSubject alloc]init];//被观察者
 3     KVObserver *kvoObser = [[KVObserver alloc]init];//观察者
 4     //注册观察者,forKeyPath中为KVOSubject的property属性
 5     [kvoSub addObserver:kvoObser forKeyPath:@"changedStr" options:NSKeyValueObservingOptionNew context:nil];
 6     //底下俩方法都可以改变值,所以打印两次
 7     kvoSub.changedStr = @"这是改变后的值";
 8     [kvoSub setValue:@"这是改变后的值" forKey:@"changedStr"];
 9     //注销观察者
10     [kvoSub removeObserver:kvoObser forKeyPath:@"changedStr"];
11 }
时间: 2024-08-03 19:42:39

通知NSNotification和KVO的使用的相关文章

【OC学习-34】通知NSNotification,类似于KVO,用于对象之间监听然后发通知提醒

通知其实和KVO类似,就是先在类A中设置通知,然后再类B中设置个监听这个通知的方法,当然可以通过这个通知方法可以传递一些参数,得到这个参数之后,一般是触发一个动作,此处举例就是触发输出一些内容而已. (1)在Child类中初始化一个实例变量为100,每次递减2,当小于90时候触发通知. //Child.h #import <Foundation/Foundation.h> @interface Child : NSObject @property(nonatomic,assign)NSInte

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

一.Delegate Delegate本质是一种程序设计模型,iOS中使用Delegate主要用于两个页面之间的数据传递.iphone中常用@protocol和delegate的机制来实现接口的功能.例如想在A的功能要在B中实现,可以在A中定义一个Protocol. protocol用法: @interface ClassA :ClassB<protocol1, protocol2> 1.首先声明一个UIView类: @interface myView  :UIView{  } @end: 2

iOS中的通知(NSNotification)

iOS中的通知(NSNotification) 前言 通知中心是一个单例.通知在iOS中是一种设计模式.每一个应用程序都有一个通知中心NSNotificationCenter实例, 专门负责协助不同对象之间的消息通信. 任何一个对象都可以向通知中心发布NSNotification, 描述自己在做什么,而任何注册了该通知的对象该特定通知发布的时候会收到这个通知. 获取通知中心对象 通过下面的方式来获取通知中心对象: 1 2 3 NSNotificationCenter *center = [NSN

IOS中的通知NSNotification

类似于Android中的广播接收者发送者 1.一般完整的通知包含三个属性 1 -(NSString *)name ;//通知的名称 2 -(id)object ;//通知发布者(是谁要发布通知) 3 -(NSDictionary *)userInfo;//一些额外的信息(通知发布者传递给通知接收者的信息内容) 2.初始化一个通知(NSnotification)对象 1 +(instancetype)notificationWithName:(NSString *)aName object:(id

IOS开发中如何使用通知NSNotification传值

通知 是在跳转控制器之间常用的传值代理方式,除了代理模式,通知更方便.便捷,一个简单的Demo实现通知的跳转传值. 输入所要发送的信息 ,同时将label的值通过button方法调用传递, - (IBAction)buttonClick:(id)sender { //添加 字典,将label的值通过key值设置传递 NSDictionary *dict =[[NSDictionary alloc]initWithObjectsAndKeys:self.textFieldOne.text,@"te

iOS利用通知(NSNotification)进行传值

通知 是在跳转控制器之间常用的传值代理方式,除了代理模式,通知更方便.便捷,一个简单的Demo实现通知的跳转传值. iOS通知传值的使用 输入所要发送的信息 ,同时将label的值通过button方法调用传递, - (IBAction)buttonClick:(id)sender { //添加 字典,将label的值通过key值设置传递 NSDictionary *dict =[[NSDictionary alloc] initWithObjectsAndKeys:self.textFieldO

iOS 通知NSNotification 使用详解

如果在一个类中想要执行另一个类中的方法可以使用通知 1.创建一个通知对象:使用notificationWithName:object: 或者 notificationWithName:object:userInfo: NSNotification* notification = [NSNotification notificationWithName:kImageNotificationLoadFailed(connection.imageURL) object:self userInfo:[N

Snail—UI学习之自定义通知NSNotification

背景是:一个界面跳转到第二个界面 然后 第一个界面发了一个通知  然后第二个界面收到这个通知后 把里面的数据取出来 在RootViewController.m中写入下面代码 #import "WJJRootViewController.h" #import "WJJFirstViewController.h" @interface WJJRootViewController (){ UITextField * _textField; } @end @implemen

(七十二)自己定义通知NSNotification实现消息传递

众所周知,iOS中一般在类之间传递消息使用较多的是delegate和block,另一种是基于通知进行的消息传递,我们经常是使用系统的通知.来实现一些功能.比如利用键盘尺寸改变的通知,我们能够依据键盘的位置改变输入框的位置,从而避免输入框被键盘遮挡. 除了利用系统的通知,我们还能够通过自己创建通知的办法来完毕一些消息传递.以XMPP登录为例,假设用户之前没有注销,那么在启动client时应该自己主动登录,登录在XMPP的工具类完毕.而当前视图在登陆完毕之前应当用网络连接的指示器(Activity