首页 > 代码库 > 键值编码和通用编程

键值编码和通用编程

键值编码(KVC)是Cocoa一个通用的用于获取和设定值的一个协议。在编程中,“通用”这词是用于描述一种可以适用于不同情境的实现方式。通用代码可以减少项目中代码总量并使得软件可以处理程序员无法预知的情景。Cocoa至始至终都很重视通用、可复用代码。

KVC版看起来需要更多代码输入。让就让我选择一个更能体现KVC价值的场景。 
首先,我们定义一个类: 
@interface CDCPerson : NSObject 

    NSString * firstName; 
    NSString * lastName; 
    NSNumber * phoneNumber; 
    NSString * emailAddress; 

- (void) setFirstName:    (NSString *)value; 
- (void) setLastName:     (NSString *)value; 
- (void) setPhoneNumber:  (NSNumber *)value; 
- (void) setEmailAddress: (NSString *)value; 
@end 

一些实际使用代码如下: 

// 假设inputValues包含我们想设定到person上的键值 
NSDictionary *inputValues; 
CDCPerson    *person = [[CDCPerson alloc] init]; 
NSEnumerator *e = [inputValues keyEnumerator]; 
id dictKey, dictValue; 
while ( dictKey = [e nextObject] ) 

    dictValue = http://www.mamicode.com/[inputValues valueForKey: dictKey];
    [person setValue: dictValue forKey: dictKey]; 


该代码段是通用的,意味着我们不需要在每次Person类添加新的实例变量的时候改变代码。 
但是还可以更好!如下就是一个上述代码的简化版本: 
// 假设inputValues包含我们想设定到person上的键值 
NSDictionary *inputValues; 
CDCPerson    *person = [[CDCPerson alloc] init]; 
[person setValuesForKeysWithDictionary: inputValues]; 

很隐晦吧?如下是Apple关于-setValuesForKeysWithDictionary:实现机制的解释: 
      通过键值对设定消息接收方的属性值,键用于识别各个属性。默认实现是对每个键值对调用setValue:forKey:,在键值对有NSNull值的情况下替换成nil。


换句话说,这和第一个例子没有什么区别。但是-setValue:forKey:到底做了些什么呢?这就是KVC的魔力所在。它实际上会找到-setFirstName:、-setLastName:、setPhoneNumber: 以及-setEmailAddress: 的实现并调用它们。如果无法找到这些,KVC会尝试几种可能直至最终将值设定到实例变量上。 

键值编码和通用编程