KVC : 键值编码,是 Key Value Coding 的简称,cocoa 的标准组成部分,是一种可以直接通过字符串的名字 ( Key ) 来访问类属性的机制,而不是通过直接调用 setter 方法、getter 方法进行访问(如果存在 setter 和 getter 方法,KVC 也会自动去调用,下篇文章会说到)。
优点
无论类中的成员是否私有,用KVC都可以强行“破门而入”,对它们正常取值和赋值。
代码示例:
//Student.h
@interface Student : NSObject
@property (nonatomic,assign)int age;
@end
//Student.m
#import "Student.h"
@interface Student()
{
@private
int _height;
}
@property (nonatomic,strong) NSString *bName;
@end
@implementation Student
@end
在 Student 实例化后,如果使用点语法,可以正常访问 age 属性,因为它是公开的,但是 height 和 bName 是私有的,使用点语法不能直接访问它们,此时 KVC 就可以正常地访问它们:
#import "Student.h"
Student *student = [Student new];
[student setValue:@175 forKey:@"height"];
int b = [[student valueForKey:@"height"]intValue];
NSLog(@"height - %i",b);
[student setValue:@"littleMing" forKey:@"bName"];
NSString *bName = [student valueForKey:@"bName"];
NSLog(@"bName - %i",bName);
只需你传入一个字典,就可以帮你自动把字典里的每一项赋值给你模型实体对应的属性。
代码示例:
//假如从服务器获取到了字典
NSDictionary *dict = @{
@"age" : @15,
@"name" : @"张大明",
@"bName" : @"张三"
};
//实例化 Student 对象
Student *student = [Student new];
//把字典里的各项元素赋值给 student 对象的各项属性
student.age = [dict[@"age"] intValue];
student.name = dict[@"name"];
student.bName = dict[@"bName"];
像以上这样赋值,没有什么问题,但是如果有 100 个属性,还需要一条一条地敲,即使用复制粘贴,也比较麻烦,此时 KVC 就比较方便:
//假如从服务器获取到了字典
NSDictionary *dict = @{
@"age" : @15,
@"name" : @"张益达",
@"bName" : @"张三"
};
//实例化 Student 对象
Student *student = [Student new];
//把字典里的各项元素赋值给 student 对象的各项属性
for (id key in dict) {
[student setValue:dict[key] forKey:key];
}
像上面这样,即使有 100 条属性,也可以轻松搞定了,但是还不够轻松,KVC 提供了另一套更为简洁的方式进行赋值,只需要你传入一个字典,就可以自动地把字典里的每一项值赋给实体类对应的属性:
//假如从服务器获取到了字典
NSDictionary *dict = @{
@"age" : @15,
@"name" : @"张大明",
@"bName" : @"张三"
};
//实例化 Student 对象
Student *student = [Student new];
//把字典里的各项元素赋值给 student 对象的各项属性
[student setValuesForKeysWithDictionary:dict];
注意:用setValuesForKeysWithDictionary或者自己写循环做字典数据转模型数据时,必须保证实体类的属性跟字典中的key名字一一对应,并且属性可以比字典多,但是绝对不能比字典的元素少!
缺点
如果key只写错,编写的时候不会报错,但是运行的时候会报错。系统默认是 crash 并报错,但我们可以通过重写
-(void)setValue:(id)value forUndefinedKey:(NSString *)key{
方法来阻止 crash 并自定义报错方式。
KVC需要解析字符串来获取所需要的内容,因此速度较慢。