赋值过程:
先找相关方法: set<key>:,_set<key>:,setIs<key>:
若没有相关方法则:+ (BOOL)accessInstanceVariablesDirectly 判断是否可以直接访问成员变量
如果 accessInstanceVariablesDirectly 返回 YES, 继续找相关成员变量_<key>,_is<key>,<key>,is<key>, 如果没找到则抛出异常 setValue: forUndefinedKey:
如果 accessInstanceVariablesDirectly 返回 NO, 直接执行 KVC 的 setValue: forUndefinedKey:
取值过程:
1 . 先找相关方法: get<key>:,<key>:
2 . 若没有相关方法则:+ (BOOL)accessInstanceVariablesDirectly 判断是否可以直接访问成员变量
3 . 如果 accessInstanceVariablesDirectly 返回 YES, 继续找相关成员变量_<key>,_is<key>,<key>,is<key>, 如果没找到则抛出异常 valueForUndefinedKey:
4 . 如果 accessInstanceVariablesDirectly 返回 NO, 直接执行 KVC 的 valueForUndefinedKey:
赋值的时候要注意:
1: 非对象类型的属性, 赋值的时候, 值不可以为空, 否则会爆报: setNilValueForKey 错误, 为了解决赋值为空的报错, 需要写下 setNilValueForKey 方法, 不至于崩溃
- @implementation Person
- // 非对象类型, 值不能为空
- - (void)setNilValueForKey:(NSString *)key{
- NSLog(@"setNilValueForKey :%@",key);
- }
- @end
2: 对不存在的属性赋值会报错: setValue:forUndefinedKey:
- -(void)setValue:(id)value forUndefinedKey:(NSString *)key
- {
- NSLog(@"%@不存在",key);
- }
赋值前验证值的合法性:
- (BOOL)validateValue:(inout id _Nullable __autoreleasing *)ioValue error:(out NSError * _Nullable __autoreleasing *)outError{
validate<value > 工作原理:
先找一下你的类中是否实现了方法 validate<Value>:error:
如果实现了就会根据实现方法里面的自定义逻辑返回 NO 或者 YES, 如果没有实现这个犯法, 则系统默认返回 YES
比如我们设置人的年龄不能超过 200 岁, 可以有如下判断:
- - (BOOL)validateAge:(inout id _Nullable __autoreleasing *)ioValue error:(out NSError * _Nullable __autoreleasing *)outError{
- NSNumber *value = (NSNumber*)*ioValue;
- int age = [value intValue];
- if (age <= 0 || age>= 200) {
- return NO;
- }
- return YES;
- }
来源: http://www.jianshu.com/p/6b3fc1c275d4