KVC的验证和异常处理
一般情况下,我们都可以正确的使用kvc,但遇到一些复杂的情况,我们无法分辨 key 或者 value 是否合法化
比如: 我们给persion 赋予一个height的属性。运行程序,最终crash ,如何规避掉这种crash。
//perion没有 height属性
[persion setValue:@181 forKeyPath:@"height"];
输出结果
2016-10-27 16:24:29.016 KVC[7307:304452] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<Persion 0x60800003f780> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key height.'
我们可以使用 - (BOOL)validateValue:(inout id _Nullable __autoreleasing )ioValue forKey:(NSString )inKey error:(out NSError * _Nullable __autoreleasing *)outError
Persion.m
@implementation Persion
/**
在类的内部,进行检查,不符合要求 返回NO ,类外部可以使用
@param ioValue 比对赋值类型
@param inKey 比对属性
@param outError 报错信息
@return 先判断是否符合要求,再使用KVC
*/
- (BOOL)validateValue:(inout id _Nullable __autoreleasing *)ioValue forKey:(NSString *)inKey error:(out NSError * _Nullable __autoreleasing *)outError {
if ([*ioValue isKindOfClass:[NSString class]] && [inKey isEqualToString:@"name"]) {
return YES;
}
return NO;
}
@end
ViewController.m
NSError *error;
NSNumber *value = @200;
if ([persion validateValue:&value forKey:@"name" error:&error]) {
[persion setValue:value forKey:@"name"];
NSLog(@"可以赋值persion.name===%@",persion.name);
}else {
NSLog(@"不可以赋值value");
NSLog(@"%@",error.debugDescription);
}
运行结果
2016-10-27 16:36:56.878 KVC[7541:315506] 不可以赋值value
这样就可以防止因为KVC的验证不到位,导致的程序crash。
KVC中keyPath的巧妙用法
情景:我们需要把一个数组里的People的名字的首字母大写,并且把新的名字存入新的数组, 这时候通常做法会是遍历整个数组,然后把每个People的name取出来,调用 capitalizedString 然后把新的String加入新的数组中。 有了KVC就有了新做法:
[array valueForKeyPath:@”name.capitalizedString”]