?一跛锌,概述
KVO,即:Key-Value Observing气笙,它提供一種機(jī)制梁剔,當(dāng)指定的對(duì)象的屬性被修改后,則對(duì)象就會(huì)接受到通知哟旗。簡(jiǎn)單的說(shuō)就是每次指定的被觀察的對(duì)象的屬性被修改后贩据,KVO就會(huì)自動(dòng)通知相應(yīng)的觀察者了。
二闸餐,使用方法
系統(tǒng)框架已經(jīng)支持KVO饱亮,所以程序員在使用的時(shí)候非常簡(jiǎn)單。
1. 注冊(cè)舍沙,指定被觀察者的屬性近上,
2. 實(shí)現(xiàn)回調(diào)方法
3. 移除觀察
三,實(shí)例:
假設(shè)一個(gè)場(chǎng)景,股票的價(jià)格顯示在當(dāng)前屏幕上拂铡,當(dāng)股票價(jià)格更改的時(shí)候壹无,實(shí)時(shí)顯示更新其價(jià)格葱绒。
1.定義DataModel,
[cpp] view plaincopy
@interface StockData : NSObject {
NSString * stockName;
float price;
}
@end
@implementation StockData
@end
2.定義此model為Controller的屬性斗锭,實(shí)例化它地淀,監(jiān)聽(tīng)它的屬性,并顯示在當(dāng)前的View里邊
[cpp] view plaincopy
- (void)viewDidLoad
{
[super viewDidLoad];
stockForKVO = [[StockData alloc] init];
[stockForKVO setValue:@"searph" forKey:@"stockName"];
[stockForKVO setValue:@"10.0" forKey:@"price"];
[stockForKVO addObserver:self forKeyPath:@"price" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:NULL];
myLabel = [[UILabel alloc]initWithFrame:CGRectMake(100, 100, 100, 30 )];
myLabel.textColor = [UIColor redColor];
myLabel.text = [stockForKVO valueForKey:@"price"];
[self.view addSubview:myLabel];
UIButton * b = [UIButton buttonWithType:UIButtonTypeRoundedRect];
b.frame = CGRectMake(0, 0, 100, 30);
[b addTarget:self action:@selector(buttonAction) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:b];
}
3.當(dāng)點(diǎn)擊button的時(shí)候岖是,調(diào)用buttonAction方法骚秦,修改對(duì)象的屬性
[cpp] view plaincopy
-(void) buttonAction
{
[stockForKVO setValue:@"20.0" forKey:@"price"];
}
4. 實(shí)現(xiàn)回調(diào)方法
[cpp] view plaincopy
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if([keyPath isEqualToString:@"price"])
{
myLabel.text = [stockForKVO valueForKey:@"price"];
}
}
5.增加觀察與取消觀察是成對(duì)出現(xiàn)的,所以需要在最后的時(shí)候璧微,移除觀察者
[cpp] view plaincopy
- (void)dealloc
{
[super dealloc];
[stockForKVO removeObserver:self forKeyPath:@"price"];
[stockForKVO release];
}
四作箍,小結(jié)
KVO這種編碼方式使用起來(lái)很簡(jiǎn)單,很適用與datamodel修改后前硫,引發(fā)的UIVIew的變化這種情況胞得,就像上邊的例子那樣,當(dāng)更改屬性的值后屹电,監(jiān)聽(tīng)對(duì)象會(huì)立即得到通知阶剑。
KVC
一,概述
KVC是KeyValueCoding的簡(jiǎn)稱危号,它是一種可以直接通過(guò)字符串的名字(key)來(lái)訪問(wèn)類屬性(實(shí)例變量)的機(jī)制牧愁。而不是通過(guò)調(diào)用Setter、Getter方法訪問(wèn)外莲。
當(dāng)使用KVO猪半、Core Data、CocoaBindings偷线、AppleScript(Mac支持)時(shí)磨确,KVC是關(guān)鍵技術(shù)。
二声邦,使用方法
關(guān)鍵方法定義在:NSKeyValueCodingprotocol
KVC支持類對(duì)象和內(nèi)建基本數(shù)據(jù)類型乏奥。
獲取值
valueForKey:,傳入NSString屬性的名字亥曹。
valueForKeyPath:邓了,傳入NSString屬性的路徑,xx.xx形式媳瞪。
valueForUndefinedKey它的默認(rèn)實(shí)現(xiàn)是拋出異常骗炉,可以重寫這個(gè)函數(shù)做錯(cuò)誤處理。
修改值
setValue:forKey:
setValue:forKeyPath:
setValue:forUndefinedKey:
setNilValueForKey:當(dāng)對(duì)非類對(duì)象屬性設(shè)置nil時(shí)材失,調(diào)用痕鳍,默認(rèn)拋出異常。
一對(duì)多關(guān)系成員的情況
mutableArrayValueForKey:有序一對(duì)多關(guān)系成員? NSArray
mutableSetValueForKey:無(wú)序一對(duì)多關(guān)系成員? NSSet
三,實(shí)例:
1.? ? 1 .Person類
2.? ? @implementation Person
3.? ? @synthesize name,age;//屬性name 將被監(jiān)視
4.? ? -(void) changeName
5.? ? {
6.? ? ? ? name=@”changeName directly”;
7.? ? }
8.? ? @end
9.
10.
11. 2.PersonMonitor類? 監(jiān)視了name屬性
12. @implementation PersonMonitor
13.
14. – (void)observeValueForKeyPath:(NSString *)keyPath
15.? ? ? ? ? ? ? ? ? ? ? ofObject:(id)object
16.? ? ? ? ? ? ? ? ? ? ? ? change:(NSDictionary *)change
17.? ? ? ? ? ? ? ? ? ? ? ? context:(void *)context
18. {
19.? ? if ([keyPath isEqual:@"name"])
20.? ? {
21.? ? ? ? NSLog(@”change happen, old:%@? new:%@”,[change objectForKey:NSKeyValueChangeOldKey],[change objectForKey:NSKeyValueChangeNewKey]);
22.? ? }
23. }
24. @end
25.
26.
27. 3測(cè)試代碼
28.
29.? ? //初始化被監(jiān)視對(duì)象
30.? ? Person *p =[[Person alloc] init];
31.? ? //監(jiān)視對(duì)象
32.? ? PersonMonitor *pm= [[PersonMonitor alloc]init];
33.? ? [p addObserver:pm forKeyPath:@"name" options:(NSKeyValueObservingOptionNew |NSKeyValueObservingOptionOld) context:nil];
34.
35. //測(cè)試前的數(shù)據(jù)
36.? ? NSLog(@”p.name is %@”,p.name);
37.
38. //通過(guò)setvalue 的方法笼呆,PersonMonitor的監(jiān)視將被調(diào)用
39.? [p setValue:@"name kvc" forKey:@"name"];
40.
41. //查看設(shè)置后的值
42.? ? NSLog(@”p name get by kvc is %@”,[p valueForKey:@"name"]);
43.
44. //效果和通過(guò)setValue 是一致的
45. p.name=@”name change by .name=”;
46.
47.? //通過(guò)person自己的函數(shù)來(lái)更改name
48.? ? ? [p changeName];
49.
50.? 結(jié)果是
51. 輸出
52. 2011-07-03 16:35:57.406 Cocoa[13970:903] p.name is name
53. 2011-07-03 16:35:57.418 Cocoa[13970:903] change happen, old:name? new:name kvc
54. 2011-07-03 16:35:57.420 Cocoa[13970:903] p name get by kvc is name kvc
55. 2011-07-03 16:35:57.421 Cocoa[13970:903] change happen, old:name kvc? new:name change by .name=
56. 最后一次修改是直接修改? 所以沒(méi)法產(chǎn)生通知
四熊响,小結(jié)
KVO/KVC這種編碼方式使用起來(lái)很簡(jiǎn)單,很適用與datamodel修改后诗赌,引發(fā)的UIVIew的變化這種情況汗茄,就像上邊的例子那樣,當(dāng)更改屬性的值后铭若,監(jiān)聽(tīng)對(duì)象會(huì)立即得到通知洪碳。