简单介绍:
KVC 是 Key-Value-Coding 的简称。
KVC 是一种可以直接通过字符串的名字 key 来访问类属性的机制,而不是通过调用 setter、getter 方法去访问。
我们可以通过在运行时动态的访问和修改对象的属性。而不是在编译时确定,KVC 是 iOS 开发中的黑魔法之一。
实现原理
常用场景
1:可以操作私有的变量或者只读的属性。
2:集合操作 比如一个数组的model 我想取其中的一个字段,一般一个循环放取出放到自己的数组里。
我们此时可以使用KVC的操作
valueForKeyPath:@"@unionOfObjects.classesName"
返回一个我们需要的数组
3:KeyPath 操作可以进行深层次嵌套操作
4:字典转Model ,注意对nil值的处理 ,以及对特殊key比如ID 的处理。
- (void)setNilValueForKey:(NSString *)key {
if ([key isEqualToString:@"name"]) {
[self setValue:@"" forKey:@name];
} else {
[super setNilValueForKey:key];
}
}
5:修改一些对象的属性,比如一些系统API没有提供足够的API ,我们自己进行KVC 操作。
比如正常的pageControl 的样式是这样
设置前 [self.testPageControl setValue:[UIImage imageNamed:@"pageControl_pre_icon"] forKeyPath:@"_pageImage"];
[self.testPageControl setValue:[UIImage imageNamed:@"pageControl_current_icon"] forKeyPath:@"_currentPageImage”];
设置后
6:XIB 或者 SB 文件中利用KVC 配置一些运行时的属性
注意:
1:用点语法编译器会做预编译检查,访问不存在的属性编译器会报错,但是用 KVC 方式编译器无法做检查,如果有错误只能运行的时候才能发现(crash)。可以利用iOS的反射机制来规避这个问题,通过@selector()获取到方法的SEL,然后通过NSStringFromSelector()将SEL反射为字符串。这样在@selector()中传入方法名的过程中,编译器会有合法性检查,如果方法不存在或未实现会报黄色警告。
可以使用FB 的一个宏定义
2:相比点语法用 KVC 方式 KVC 的效率会稍低一点,但是灵活,可以在程序运行时决定访问哪些属性。所以在使用KVC的时候,建议最好不要手动设置属性的setter、getter,这样会导致搜索步骤变长。