OC中另外的一个常用技术:通知(Nofitication)
其实这里的通知和之前说到的KVO功能很想,也是用于监听操作的,但是和KVO不同的是,KVO只用来监听属性值的变化,这个发送监听的操作是系统控制的,我们控制不了,我们只能控制监听操作,类似于Android中系统发送的广播,我们只能接受。但是通知就不一样了,他的监听发送也是又我们自己控制,我们可以在任何地方任何时机发送一个通知,类似于Android中开发者自己发送的广播。从这一点看来,通知的使用场景更为广泛了。
下面就来看一下例子:
还是护士和小孩的那个例子
Children.h[objc] view plaincopy 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 plaincopy 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 plaincopy 1. //发送通知
2. //这里和KVO的区别,我们可以手动的发送通知
3. //注意通知的名称,传递的参数必须和定义通知的地方的参数值要一致
4. //将Children对象传递过去
5. [[NSNotificationCenter defaultCenter] postNotificationName:@"happyValueNotification" object:self];
我们在属性值发生变化的地方发送一个通知:NSNotificationCenter
第一个参数:通知的名称,这个名称必须和后面接受通知的名称一致
第二个参数:可以传递的一个参数对象
Nure.h[objc] view plaincopy 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 plaincopy 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 plaincopy 1. //监听一个通知,当收到通知时,调用notificationAction方法
2. [[NSNotificationCenter defaultCenter] addObserver:
self selector:
@selector(notificationAction) name:@"happyValueNotification" object
:nil];
使用addObserver方法来监听通知
第一个参数:监听者对象
第二个参数:监听处理逻辑的方法
第三个参数:通知的名称
第四个参数:通知发送的时候传递过来的参数对象
1、处理通知的方法[objc] view plaincopy 1. - (
void) notificationAction:(
NSNotification *)notification{
2. //这里我们拿到Children对象进行操作
3.
Children *children = notification.object;
4. NSLog(@"触发通知");
5. }
这里会传递一个NSNotification对象,通过object属性可以获取到监听对象了,因为我们在发送通知的时候传递过来的这个对象。那么这里我们就可以获取监听对象的属性值了,但是这里我们如果想知道属性值变化前和变化后的值,我们可以在Children类中在定义一个属性专门用来记录旧的属性值,这样就可以了。
2、销毁方法[objc] view plaincopy 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.