KVO
APP开发技术QQ群:347072638
一,概述
KVO,
即:
Key-Value Observing
,它提供一种机制,当指定的对象的属性被修改后,则对象就会接受到通知。简单的说就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知相应的观察者了。
二,使用方法
系统框架已经支持KVO,所以程序员在使用的时候非常简单。
1. 注册,指定被观察者的属性,
2. 实现回调方法
3. 移除观察
三,实例:
假设一个场景,股票的价格显示在当前屏幕上,当股票价格更改的时候,实时显示更新其价格。
1.定义DataModel,
- @interface StockData : NSObject {
- NSString * stockName;
-
float
price; - }
- @end
- @implementation StockData
- @end
2.定义此model为Controller的属性,实例化它,监听它的属性,并显示在当前的View里边
-
– (
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.当点击button的时候,调用buttonAction方法,修改对象的属性
-
-(
void
) buttonAction - {
-
[stockForKVO setValue:@
“20.0”
forKey:@
“price”
]; - }
4. 实现回调方法
-
-(
void
)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(
void
*)context - {
-
if
([keyPath isEqualToString:@
“price”
]) - {
-
myLabel.text = [stockForKVO valueForKey:@
“price”
]; - }
- }
5.增加观察与取消观察是成对出现的,所以需要在最后的时候,移除观察者
-
– (
void
)dealloc - {
- [super dealloc];
-
[stockForKVO removeObserver:self forKeyPath:@
“price”
]; - [stockForKVO release];
- }
四,小结
KVO这种编码方式使用起来很简单,很适用与datamodel修改后,引发的UIVIew的变化这种情况,就像上边的例子那样,当更改属性的值后,监听对象会立即得到通知。
KVC
一,概述
KVC
是KeyValueCoding
的简称,它是一种可以直接通过字符串的名字(key)来访问类属性的机制。而不是通过调用Setter、Getter方法访问。
当使用KVO
、Core Data、CocoaBindings、AppleScript(Mac支持)时,KVC是关键技术。
二,使用方法
关键方法定义在:NSKeyValueCodingprotocol
KVC
支持类对象和内建基本数据类型。
获取值
valueForKey:
,传入NSString
属性的名字。
valueForKeyPath:
,传入NSString
属性的路径,xx.xx形式。
valueForUndefinedKey
它的默认实现是抛出异常,可以重写这个函数做错误处理。
修改值
setValue:forKey:
setValue:forKeyPath:
setValue:forUndefinedKey:
setNilValueForKey:
当对非类对象属性设置nil
时,调用,默认抛出异常。
一对多关系成员的情况
mutableArrayValueForKey
:有序一对多关系成员
NSArray
mutableSetValueForKey
:无序一对多关系成员
NSSet
三,实例:
1.
1
.Person
类
2.
@implementation
Person
3.
@synthesize
name,age;
//
属性
name
将被监视
4.
-(void)
changeName
5.
{
6.
name=@”changeName
directly”;
7.
}
8.
@end
9.
10.
11.
2.PersonMonitor
类
监视了
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
测试代码
28.
29.
//
初始化被监视对象
30.
Person
*p
=[[Person
alloc]
init];
31.
//
监视对象
32.
PersonMonitor
*pm=
[[PersonMonitor
alloc]init];
33.
[p
addObserver:pm
forKeyPath:@”name”
options:(NSKeyValueObservingOptio
nNew
|NSKeyValueObservingOptio
nOld)
context:nil];
34.
35.
//
测试前的数据
36.
NSLog(@”p.name
is
%@”,p.name);
37.
38.
//
通过
setvalue
的方法,
PersonMonitor
的监视将被调用
39.
[p
setValue:@”name
kvc”
forKey:@”name”];
40.
41.
//
查看设置后的值
42.
NSLog(@”p
name
get
by
kvc
is
%@”,[p
valueForKey:@”name”]);
43.
44.
//
效果和通过
setValue
是一致的
45.
p.name=@”name
change
by
.name=”;
46.
47.
//
通过
person
自己的函数来更改
name
48.
[p
changeName];
49.
50.
结果是
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.
最后一次修改是直接修改
所以没法产生通知
四,小结
KVO/
KVC
这种编码方式使用起来很简单,很适用与datamodel修改后,引发的UIVIew的变化这种情况,就像上边的例子那样,当更改属性的值后,监听对象会立即得到通知。