键值编码允许开发者通过名字访问对象属性, 而无需调用明确的存取方法, 这样,就可以在运行时确定属性的绑定, 而不是在编译时确定.(可以动态访问属性)例如可以通过[object valueForKey: someProperty];表达式来请求由字符串变量someProperty命名的属性值, 也能用
[object setValue: someValue forKey: someProperty];来给someProperty命名的属性赋值.
这种间接访问能让开发者在运行时而非编译时决定访问那个属性, 从而得到更灵活和易于重用的对象.
为了获得这种灵活性, 对象需要用特定的方式来命名方法, 这种命名约定就称为键值编码(KVC).
和其他观察者机制的对比:
相比委托 / Notification, KVO的开销更小, 被观察的对象不需要有任何额外的代码来通知观察者,而如果没有观察者, KVO就没有运行时的消耗. 只有对象被真正观察时, KVO系统才添加通知代码. 这就让KVO在性能上至关重要的场合变得很有吸引力.
objectForKey 和 objectForKeyPath区别
key(键)和keyPath(键路径)之间的区别在于,后者可以包含嵌套关系, 可用点分开.
如下面方法是等价的:
[[self department] name];
[self valueForKeyPath: @“department.name”];
如果valueForKey: @“department.name”会试图获取department.name这个属性. 大部分会抛出异常.
相比较, keyPath会更灵活, 而key版本的稍微快一些. 如果键是通过参数传给, 一般会用valueForKeyPath:来为调用者提供最大的灵活性, 如果键是硬编码(固定的),则选择valueForKey: .
用KVC实现高阶消息传递:
NSArray
*array =
@[
@"abc"
,
@"dcv"
,
@"dpa"
]
;
NSArray *capitalizedArray = [array valueForKey:@"capitalizedString"];
NSArray *capitalizedLengthArray = [array valueForKeyPath:@"capitalizedString.length”];
//
对
array
中的每一个元素调用
capitalizedString,
然后调用
length,
在吧返回值封装进
NSNumber
对象
.
结果被收集进名为
capitalizedLengthArray
中
NSLog(@"%@ %@", capitalizedArray, capitalizedLengthArray);
打印结果:
2015-02-08 12:31:01.846 KVC[12930:2569897] (
Abc,
Dcv,
Dpa
) (
3,
3,
3
Abc,
Dcv,
Dpa
) (
3,
3,
3
)
容器操作符:(更多查看:key-value Coding Programing Guide)
KVC还提供了很复杂的函数, 比如说自动对一组数字求和或者求平均值。
NSArray
*array =
@[
@"abc"
,
@"dcv"
,
@"dpa"
]
;
NSInteger totalLength = [[array valueForKeyPath : @"@sum.length" ] integerValue ];
NSInteger totalLength = [[array valueForKeyPath : @"@sum.length" ] integerValue ];
NSLog(@"totalLength, %ld", totalLength);
打印结果为9