你的位置:首页 > 操作系统

[操作系统]OC语法之KVC与KVO


1、Key-Value Coding (KVC)

KVC,即是指 NSKeyValueCoding,一个非正式的 Protocol,提供一种机制来间接访问对象的属性。KVO 就是基于 KVC 实现的关键技术之一。

一个对象拥有某些属性。比如说,一个 Person 对象有一个 name 和一个 address 属性。以 KVC 说法,Person 对象分别有一个 value 对应他的 name 和 address 的 key。 key 只是一个字符串,它对应的值可以是任意类型的对象。从最基础的层次上看,KVC 有两个方法:一个是设置 key 的值,另一个是获取 key 的值。如下面的例子:

1
2
3
4
5
6
7
8
9
10
11
12
void changeName(Person *p, NSString *newName)
{
 
    // using the KVC accessor (getter) method
    NSString *originalName = [p valueForKey:@"name"];
 
    // using the KVC  accessor (setter) method.
    [p setValue:newName forKey:@"name"];
 
    NSLog(@"Changed %@'s name to: %@", originalName, newName);
 
}



现在,如果 Person 有另外一个 key 配偶(spouse),spouse 的 key 值是另一个 Person 对象,用 KVC 可以这样写:

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
void logMarriage(Person *p)
{
 
    // just using the accessor again, same as example above
    NSString *personsName = [p valueForKey:@"name"];
 
    // this line is different, because it is using
    // a "key path" instead of a normal "key"
    NSString *spousesName = [p valueForKeyPath:@"spouse.name"];
 
    NSLog(@"%@ is happily married to %@", personsName, spousesName);
 
}



key 与 key pat 要区分开来,key 可以从一个对象中获取值,而 key path 可以将多个 key 用点号 “.” 分割连接起来,比如:

[p valueForKeyPath:@"spouse.name"];



相当于这样……

[[p valueForKey:@"spouse"] valueForKey:@"name"];



好了,以上是 KVC 的基本知识,接着看看 KVO。

Key-Value Observing (KVO)

Key-Value Observing (KVO) 建立在 KVC 之上,它能够观察一个对象的 KVC key path 值的变化。举个例子,用代码观察一个 person 对象的 address 变化,以下是实现的三个方法:

  • watchPersonForChangeOfAddress: 实现观察
  • observeValueForKeyPath:ofObject:change:context: 在被观察的 key path 的值变化时调用。
  • dealloc 停止观察

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
static NSString *const KVO_CONTEXT_ADDRESS_CHANGED = @"KVO_CONTEXT_ADDRESS_CHANGED"
 
@implementation PersonWatcher
 
-(void) watchPersonForChangeOfAddress:(Person *)p
{
 
    // this begins the observing
    [p addObserver:self
        forKeyPath:@"address"
           options:0
           context:KVO_CONTEXT_ADDRESS_CHANGED];
 
    // keep a record of all the people being observed,
    // because we need to stop observing them in dealloc
    [m_observedPeople addObject:p];
}
 
// whenever an observed key path changes, this method will be called
- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context
 
{
    // use the context to make sure this is a change in the address,
    // because we may also be observing other things
    if(context == KVO_CONTEXT_ADDRESS_CHANGED) {
        NSString *name = [object valueForKey:@"name"];
        NSString *address = [object valueForKey:@"address"];
        NSLog(@"%@ has a new address: %@", name, address);
    }
}
 
-(void) dealloc;
{
 
    // must stop observing everything before this object is
    // deallocated, otherwise it will cause crashes
    for(Person *p in m_observedPeople){
        [p removeObserver:self forKeyPath:@"address"];
    }
 
    [m_observedPeople release];
    m_observedPeople = nil;
 
    [super dealloc];
 
}
 
-(id) init;
{
    if(self = [super init]){
        m_observedPeople = [NSMutableArray new];
    }
 
    return self;
}
 
@end



这就是 KVO 的作用,它通过 key path 观察对象的值,当值发生变化的时候会收到通知。




山东旅游攻略大全山东旅游攻略自助游山东旅游报价价格山东旅游景点推荐山东旅游团报价广州到深圳野生动物园自驾怎么走?广州到深圳动物园开车多长时间? 四月赏杜鹃 与大明山相约一场春天 深圳野生动物园游玩需要多长时间?深圳动物园几个小时能玩完? 深圳野生动物园清明节有什么活动?深圳动物园清明节活动介绍? 珠海农科奇观郁金香开了吗?2015珠海农科奇观郁金香开花时间? 2015珠海农科奇观郁金香花展时间?珠海农科奇观郁金香花展什么时候? 春节宝趣玫瑰园看花展门票多少钱?广州从化宝趣玫瑰世界花展门票价格? 2015春节去从化怎么玩?从化春节游玩推荐? 成都熊猫基地开放时间是什么时候? 游走大连寻找海上观赏日出的最佳地 平乐古镇门票多少钱,开放时间是什么时候? 龙脊梯田什么时候去最好? 去香港购物选购手机要注意什么? 怎样办理港澳通行证?办港澳通行证需要多少天?费用每人是多少? 去香港玩顺便买iPhone?能带几台? 什么时候去香港最划算? AQ12EA6R8JAJME Datasheet AQ12EA6R8JAJME Datasheet SQCAEA130GATWE Datasheet SQCAEA130GATWE Datasheet AQ12EA6R8JAJME\500 Datasheet AQ12EA6R8JAJME\500 Datasheet 牡丹江去香港游 牡丹江去香港游 牡丹江去香港游 伊春去港澳游 伊春去港澳游 伊春去港澳游 内蒙古通辽去香港游 内蒙古通辽去香港游 内蒙古通辽去香港游