通过key-value来间接的访问属性
基本使用
成员变量
默认是@protect
想让外部调用@public 可以用-> : p->_pubname 来调用
KVC取值过程分析
先找相关方法(步骤1),再找相关变量(步骤4)
赋值过程:
-
先找相关方法 set:, _set:, setIs: 按顺序,如果前面的方法没找到,执行后面的方法
先找相关方法,再找相关变量 -
若没有相关方法 + (BOOL)accessInstanceVariablesDirectly,判断是否可以直接方法成员变量 : 默认返回YES
-
如果是判断是NO,直接执行KVC的setValue:forUndefinedKey:(系统抛出一个异
常,未定义key) -
如果是YES,继续找相关成员变量_key, _isKey ,key ,isKey
找到这些名字的变量,然后赋值 -
方法或成员都不存在,setValue:
forUndefinedKey:方法,默认是抛出异常
4 寻找相关变量
.h
NSString *_name;//1
NSString *_isName;//2
NSString *name;//3
NSString *isName;//4
.m
[p setValue:@"yuanhao" forKey:@"name"];;
NSLog(@"name = %@",p->_name);//1.1
NSLog(@"_name = %@",p->_isName);//2.1
NSLog(@"isName = %@",p->name);//3.1
NSLog(@"_isName = %@",p->isName);//4.1
如果没有都没有注释,1.1有值
注释了1 , 2.1打印值,其它都为null
注释了1,2 , 3.1打印值,其它为null
...
给key name赋值,按步骤4的顺序,先给_name赋值,如果没有_name的变量,再给_isName赋值.....
取值过程:
-
先找相关方法 getKey, key
-
若没有相关方法 + (BOOL)accessInstanceVariablesDirectly,判断是否可以直接方法成员变量
-
如果是判断是NO,直接执行KVC的valueForUndefinedKey:(系统抛出一个异
常,未定义key) -
如果是YES,继续找相关变量_key ,_isKey, key ,isKey
-
方法或成员都不存在,valueForUndefinedKey:方法,默认是抛出异常
forKeyPath
访问多级属性
setValue:<#(nullable id)#> forKeyPath:<#(nonnull NSString *)#>
@property (nonatomic, strong) TZDog* dog;
比如p中有某个属性,是里一个类的实例,这个类的实例又有属性.
[p setValue:@“tom” forKeyPath:@“dog.name”];
KVC异常处理 正确性验证
可以复写这些方法来捕获错误
对于非对象类型,值不能为空
-(void)setNilValueForKey:(NSString *)key{
}
-(void)setValue:(id)value forUndefinedKey:(NSString *)key{}
-(id)valueForUndefinedKey:(NSString *)key
KVC进阶用法
1. KVC与字典
- setValueForKeysWithDictionary: //字典转模型
[self dictionaryWithValuesForKeys:<#(nonnull NSArray<NSString *> *)#>] //
- (NSDictionary<NSString *, id> *)dictionaryWithValuesForKeys:(NSArray<NSString *> *)keys; //模型转字典
2. KVC消息传递
给数组的每个成员都发送消息
- (void)arrayKVCTest{
NSArray *arr =@[@"monday",@"yuanhao",@"fengfeng"];
NSArray *lengthArr = [arr valueForKey:@"length"];
NSLog(@"%@",lengthArr);
(
6,
7,
8
)
3. KVC容器操作
- 聚合操作符 @avg,@count,@max,@min,@sum
- 数组操作符
- 嵌套集合(array&set)操作
- 聚合操作
p1.height = 1.65
p2.height = 1.55
arr addObject:p
[arr valueForKey:@"height"]; //获取所有的成员的高度
//平均身高
[[arr valueForKey:@"@avg.height"] floatValue]
- 数组操作符
[arr valueForKey:@"@distindtUnionOfObjects.height"] //去重