OC学习篇之---通知(NSNotificationCenter)

本文详细介绍了Objective-C中的通知机制,对比KVO技术,解释了通知如何提供更灵活的监听方式。通过护士和小孩的例子,展示了如何发送和接收通知,包括如何在属性变化时触发通知,以及如何在类中实现通知的监听和移除。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

 

在前一篇文章中我们介绍了OC中很常用的两个技术:KVC和KVO: http://blog.youkuaiyun.com/jiangwei0910410003/article/details/41912937,今天我们来看一下OC中另外的一个常用技术:通知(Nofitication)

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

 

下面就来看一下例子:

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

Children.h

 

[objc]  view plain  copy
 在CODE上查看代码片派生到我的代码片
  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.   
  9. #import <Foundation/Foundation.h>  
  10.   
  11. @interface Children : NSObject  
  12.   
  13. @property NSInteger *hapyValue;  
  14.   
  15.   
  16. @end  
定义了一个属性:hapyValue

 

 

Children.m

 

[objc]  view plain  copy
 在CODE上查看代码片派生到我的代码片
  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.   
  9. #import "Children.h"  
  10.   
  11. @implementation Children  
  12.   
  13. - (id) init{  
  14.     self = [super init];  
  15.     if(self != nil){  
  16.         //启动定时器  
  17.         [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerAction) userInfo:nil repeats:YES];  
  18.         self.hapyValue= 100;  
  19.     }  
  20.     return self;  
  21. }  
  22.   
  23. - (void) timerAction:(NSTimer *) timer{  
  24.     //使用set方法修改属性值,才能触发KVO  
  25.     _hapyValue--;  
  26.     NSLog(@"%@",_hapyValue);  
  27.     if(_hapyValue <80){  
  28.         //发送通知  
  29.         //这里和KVO的区别,我们可以手动的发送通知  
  30.         //注意通知的名称,传递的参数必须和定义通知的地方的参数值要一致  
  31.         //将Children对象传递过去  
  32.         [[NSNotificationCenter defaultCenter] postNotificationName:@"happyValueNotification" object:self];  
  33.     }  
  34.   
  35. }  
  36.   
  37.   
  38. @end  
定义了一个定时器,但是我们看到这里的timerAction方法中就开始发送一个通知了:

 

 

[java]  view plain  copy
 在CODE上查看代码片派生到我的代码片
  1. //发送通知  
  2. //这里和KVO的区别,我们可以手动的发送通知  
  3. //注意通知的名称,传递的参数必须和定义通知的地方的参数值要一致  
  4. //将Children对象传递过去  
  5. [[NSNotificationCenter defaultCenter] postNotificationName:@"happyValueNotification" object:self];  
我们在属性值发生变化的地方发送一个通知:NSNotificationCenter

 

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

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

 

Nure.h

 

[objc]  view plain  copy
 在CODE上查看代码片派生到我的代码片
  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.   
  9. #import <Foundation/Foundation.h>  
  10.   
  11. @interface Nure : NSObject  
  12.   
  13. @end  

Nure.m

 

 

[objc]  view plain  copy
 在CODE上查看代码片派生到我的代码片
  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.   
  9. #import "Nure.h"  
  10. #import "Children.h"  
  11.   
  12. @implementation Nure  
  13.   
  14. - (id) init{  
  15.     self = [super init];  
  16.     if(self != nil){  
  17.           
  18.         //监听一个通知,当收到通知时,调用notificationAction方法  
  19.         [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationAction) name:@"happyValueNotification" object:nil];  
  20.           
  21.     }  
  22.     return self;  
  23. }  
  24.   
  25.   
  26. - (void) notificationAction:(NSNotification *)notification{  
  27.     //这里我们拿到Children对象进行操作  
  28.     Children *children = notification.object;  
  29.     NSLog(@"触发通知");  
  30. }  
  31.   
  32. - (void)dealloc{  
  33.     //移除指定的通知,不然会造成内存泄露  
  34.     [[NSNotificationCenter defaultCenter] removeObserver:self name:@"happyValueNotification" object:nil];  
  35.       
  36.     //Children对象可以添加多个通知  
  37.     //下面的方法是可以移除Children中所有通知  
  38.     [[NSNotificationCenter defaultCenter] removeObserver:self];  
  39. }  
  40.   
  41. @end  
在Nure类中我们开始接受通知了:

 

 

[objc]  view plain  copy
 在CODE上查看代码片派生到我的代码片
  1. //监听一个通知,当收到通知时,调用notificationAction方法  
  2. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationAction) name:@"happyValueNotification" object:nil];  
使用addObserver方法来监听通知

 

第一个参数:监听者对象

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

第三个参数:通知的名称

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

 

1、处理通知的方法

 

[objc]  view plain  copy
 在CODE上查看代码片派生到我的代码片
  1. - (void) notificationAction:(NSNotification *)notification{  
  2.     //这里我们拿到Children对象进行操作  
  3.     Children *children = notification.object;  
  4.     NSLog(@"触发通知");  
  5. }  
这里会传递一个NSNotification对象,通过object属性可以获取到监听对象了,因为我们在发送通知的时候传递过来的这个对象。那么这里我们就可以获取监听对象的属性值了,但是这里我们如果想知道属性值变化前和变化后的值,我们可以在Children类中在定义一个属性专门用来记录旧的属性值,这样就可以了。

 

 

2、销毁方法

 

[objc]  view plain  copy
 在CODE上查看代码片派生到我的代码片
  1. - (void)dealloc{  
  2.     //移除指定的通知,不然会造成内存泄露  
  3.     [[NSNotificationCenter defaultCenter] removeObserver:self name:@"happyValueNotification" object:nil];  
  4.       
  5.     [[NSNotificationCenter defaultCenter] removeObserver:self];  
  6. }  

 

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

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

 

总结

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值