在 iOS: MVC 中,我貼了張經(jīng)典圖:
其中的Model向Controller通信的Noification&KVO為何物呢? 在功能上說(shuō),delegate、Notification以及KVO的功能類似,都是作用于OC中對(duì)象的消息通信。但三者的使用場(chǎng)景是不同的。簡(jiǎn)單的說(shuō)Delegate是一種回掉函數(shù),更多的用在一對(duì)一的場(chǎng)合,可參考 iphone:delegate機(jī)制 ;Notification 用得較少,使用Notification Center,類似廣播方式,所以更適合一對(duì)多的通信;KVO,key-Value-Observing,觀察者模式,適用于偵聽(tīng)另一對(duì)象的屬性的變化。 三者的詳細(xì)區(qū)別可以參考另一博文:http://mobile.51cto.com/iphone-386316.htm Notification: notification的使用十分簡(jiǎn)單,直接看代碼:
//使用類方法獲取實(shí)例
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
//增加2個(gè)消息監(jiān)聽(tīng),消息名都為logInfo,一個(gè)在本對(duì)象中監(jiān)聽(tīng),監(jiān)聽(tīng)方法GetInfo;一個(gè)在oneobj對(duì)象監(jiān)聽(tīng),監(jiān)聽(tīng)方法oneObjHandleInfo。
[center addObserver:self selector:@selector(GetInfo:) name:@'logInfo' object:nil];
[center addObserver:oneobj selector:@selector(oneObjHandleInfo:) name:@'logInfo' object:nil];
//發(fā)送消息,消息名logInfo,傳遞數(shù)據(jù)為一個(gè)NSString
[center postNotificationName:@'logInfo' object:@'00000'];
對(duì)應(yīng)的2個(gè)接收方法: //本對(duì)象中...
-(void) GetInfo:(NSNotification *) notificaion{
//取得接受數(shù)據(jù)并打印
NSString *data = [notificaion object];
NSLog(@'>> %@',data);
}
//OneObj對(duì)象中...
-(void) oneObjHandleInfo:(NSNotification*) notification{
//取得接受數(shù)據(jù)并打印
NSString *data = [notification object];
NSLog(@'>>OneOBJ %@',data);
}
這樣就實(shí)現(xiàn)了post一個(gè)消息的時(shí)候,對(duì)應(yīng)的2個(gè)監(jiān)聽(tīng)者都能收到消失并做出相關(guān)處理。最后要注意的是在不用的時(shí)候把對(duì)應(yīng)的監(jiān)聽(tīng)給remove掉。 [center removeObserver:self name:@'logInfo' object:nil];
[center removeObserver:oneobj name:@'logInfo' object:nil];
KVO: 在看KVO之前,有必要先了解下KVC,即,Key-Value Coding 鍵值對(duì)編程。通過(guò)key-value可以方便的存取數(shù)據(jù)。 具體的操作簡(jiǎn)單說(shuō)就是:setValue:forKey: valueForKey: //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
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']);
更詳細(xì)的KVC介紹可以參考: http://marshal./tech/objc-%E4%BD%BF%E7%94%A8kvc KVO是基于kvc實(shí)現(xiàn)的,采取的是觀察者的模式: book4=[[Book alloc] init];
//增加觀察者,為本類,keypath為book中的price對(duì)象,所以為price
[book4 addObserver:self forKeyPath:@'price' options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];
//修改值
[book4 setValue:@'4' forKey:@'price'];
//回掉方法
-(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']);
}
}
這樣便實(shí)現(xiàn)了當(dāng)對(duì)象屬性改變時(shí),做出相應(yīng)反應(yīng)。 更詳細(xì)KVO實(shí)現(xiàn)也可以參照:http://blog.csdn.net/yuquan0821/article/details/6646400 那KVC、KVO內(nèi)部是如何實(shí)現(xiàn)的呢? “一個(gè)對(duì)象在調(diào)用setValue的時(shí)候,(1)首先根據(jù)方法名找到運(yùn)行方法的時(shí)候所需要的環(huán)境參數(shù)。(2)他會(huì)從自己isa指針結(jié)合環(huán)境參數(shù),找到具體的方法實(shí)現(xiàn)的接口。(3)再直接查找得來(lái)的具體的方法實(shí)現(xiàn)。 因?yàn)镵VC的實(shí)現(xiàn)機(jī)制,可以很容易看到某個(gè)KVC操作的Key,而后也很容易的跟觀察者注冊(cè)表中的Key進(jìn)行匹對(duì)。假如訪問(wèn)的Key是被觀察的Key,那么我們?cè)趦?nèi)部就可以很容易的到觀察者注冊(cè)表中去找到觀察者對(duì)象,而后給他發(fā)送消息。” 詳細(xì)check:http://www./Cocoadev/KVO-20100222-0627.asp
iOS中oc通信的通知和KVO大概就是這些了。
|
|