首先KVC是什么,通过官方文档查询,它是一种机制,通过NSKEYValueCoding协议,简直编码方式间接访问成员变量
普通对象赋值取值过程
keyvalue赋值过程
例如
myPerson *p = [[myPerson alloc] init];
[p setValue:@"hg" forKey:@"name"];
首先它会看 myPerson 里面有没有set<key>,_set<key>的方法 ,如果有就通过set<key>,_set<key>这个顺序来进行赋值,如果没有,则看accessinstanceVariablesDirectly是否返回YES,如果返回YES,那么在赋值过程中,那么它就会先看有没有_name的成员变量有的话赋值给_name,如果没有就再看是否赋值给_isName,然后才就再看是否赋给name,再然后才赋给isName;
keyvalue取值过程
从get<key>---><key> 如果两个方法均未实现
那么accessinstanceVariablesDirectly(是否开启间接访问)要返回YES(默认为返回YES),那么就会自动访问其它一系列的成员变量_<key>,_is<key>,<key>,is<key>,如果设置为NO,则不会去读取这些成员变量。
数组取值赋值过程
keyvalue取值过程
例如:
myPerson *p = [myPerson new];
p.myArr = [NSMutableArray arrayWithObjects:@"data0", @"data1", @"data2", @"data3", nil];
NSArray*arr = [p valueForKey:@"datas"];
NSLog(@"datas = %@", arr);
//输出 来了 迭代编译---->
pens = {(
pen3,
pen2,
pen1,
pen0
)}
首先会从countOf(key),enumeratorOf(key)或者memberOf(key)来取值
,如果重写了这三个方法则都必须实现
// 个数
- (NSUInteger)countOfDatas {
return[self.myArr count];
}
// 是否包含这个成员对象
- (id)memberOfDatas:(id)object {
return[self.myArr containsObject:object] ? object :nil;
}
同理集合NSSet的赋值过程也是一样的
在取NSArry的某个元素时,如果重写了以上方法,那么也必须重写objectIn(key)AtIndex方法来取值,但是NSSet中,是没有这个方法的,因为它是哈希表实现的,是散列的,无序的,它必须通过迭代器来取值,那么也就要实现enumeratorOfDatas才能进行取值
// 获取值
- (id) objectInDatasAtIndex:(NSUInteger)index {
return self.myArr[index];
}
// 迭代器
- (id)enumeratorOfDatas {
// objectEnumerator
NSLog(@"来了 迭代编译");
return [self.myArr reverseObjectEnumerator];
}
需要注意的是KVC的异常处理,在类中实现:
- (void)setValue:(id)value forUndefinedKey:(NSString *)key{
NSLog(@"不能对不存在的健赋值");
}
- (id)valueForUndefinedKey:(NSString *)key{
NSLog(@"不能对不存在的键取值");
return @"error";
}
来进行操作,当设置到不存在的键值时给予处理,和拿不存在的键值时进行处理,防止相应的奔溃。
网友评论