Notification:
notification的使用十分简单,直接看代码:
1
2
3
4
5
6
7
8
9
|
//使用类方法获取实例 NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; //增加2个消息监听,消息名都为logInfo,一个在本对象中监听,监听方法GetInfo;一个在oneobj对象监听,监听方法oneObjHandleInfo。 [center addObserver:self selector:@selector(GetInfo:) name:@ "logInfo" object:nil]; [center addObserver:oneobj selector:@selector(oneObjHandleInfo:) name:@ "logInfo" object:nil]; //发送消息,消息名logInfo,传递数据为一个NSString [center postNotificationName:@ "logInfo" object:@ "00000" ]; |
对应的2个接收方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
//本对象中... -( void ) GetInfo:(NSNotification *) notificaion{ //取得接受数据并打印 NSString *data = [notificaion object]; NSLog(@ ">> %@" ,data); } //OneObj对象中... -( void ) oneObjHandleInfo:(NSNotification*) notification{ //取得接受数据并打印 NSString *data = [notification object]; NSLog(@ ">>OneOBJ %@" ,data); } |
这样就实现了post一个消息的时候,对应的2个监听者都能收到消失并做出相关处理。最后要注意的是在不用的时候把对应的监听给remove掉。
1
2
|
[center removeObserver:self name:@ "logInfo" object:nil]; [center removeObserver:oneobj name:@ "logInfo" object:nil]; |
KVO:
在看KVO之前,有必要先了解下KVC,即,Key-Value Coding 键值对编程。通过key-value可以方便的存取数据。
具体的操作简单说就是:setValue:forKey: valueForKey:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
//book Object //.h # import <Foundation/Foundation.h> @ class Author; @ interface Book : NSObject{ NSString *name; Author *author; float price; NSArray *relativeBooks; } @end //.m # import "Book.h" @implementation Book @end |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
Book *book = [[Book alloc] init]; [book setValue:@ "iOS book" forKey:@ "name" ]; NSString *name = [book valueForKey:@ "name" ]; NSLog(@ ">> %@" ,name); Author *author = [[Author alloc] init]; [author setValue:@ "Zhan" forKey:@ "name" ]; [book setValue:author forKey:@ "author" ]; NSString *authorName = [book valueForKeyPath:@ "author.name" ]; NSLog(@ ">> %@" ,authorName); [book setValue:@ "100" forKey:@ "price" ]; NSLog(@ ">> %@" ,[book valueForKey:@ "price" ]); Book *book1 = [[Book alloc] init]; [book1 setValue:@ "4" forKey:@ "price" ]; Book *book2 = [[Book alloc] init]; [book2 setValue:@ "6" forKey:@ "price" ]; NSArray *books = [NSArray arrayWithObjects:book1,book2,nil]; [book setValue:books forKey:@ "relativeBooks" ]; NSLog(@ ">>%@" ,[book valueForKeyPath:@ "relativeBooks.price" ]); |
KVO是基于kvc实现的,采取的是观察者的模式:
1
2
3
4
5
|
book4=[[Book alloc] init]; //增加观察者,为本类,keypath为book中的price对象,所以为price [book4 addObserver:self forKeyPath:@ "price" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil]; //修改值 [book4 setValue:@ "4" forKey:@ "price" ]; |
1
2
3
4
5
6
7
8
9
10
11
12
|
//回掉方法 -( void ) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:( void *)context{ NSLog(@ "cel back" ); if ([keyPath isEqual:@ "price" ]){ NSLog(@ ">>>>>>>price is changed" ); NSLog(@ "old price is %@" ,[change objectForKey:@ "old" ]); NSLog(@ "new price is %@" ,[change objectForKey:@ "new" ]); } } |
这样便实现了当对象属性改变时,做出相应反应。
那KVC、KVO内部是如何实现的呢?
“一个对象在调用setValue的时候,(1)首先根据方法名找到运行方法的时候所需要的环境参数。(2)他会从自己isa指针结合环境参数,找到具体的方法实现的接口。(3)再直接查找得来的具体的方法实现。
因为KVC的实现机制,可以很容易看到某个KVC操作的Key,而后也很容易的跟观察者注册表中的Key进行匹对。假如访问的Key是被观察的Key,那么我们在内部就可以很容易的到观察者注册表中去找到观察者对象,而后给他发送消息。”