KVC的内部实现
2018-12-22 本文已影响0人
丹丹十个胆小鬼
1、kvc的常用方法
- (nullable id)valueForKeyPath:(NSString *)keyPath;
- (void)setValue:(nullable id)value forKeyPath:(NSString *)keyPath;
- (void)setValuesForKeysWithDictionary:(NSDictionary<NSString *, id> *)keyedValues;
我们在把字典数据转成对象模型时,一般会用到setValuesForKeysWithDictionary:
此方法内部是怎么实现都做了那些事情呢?
- 1、遍历字典,
- 2、调用 [flagM setValue:obj forKeyPath:key];
// [self setValuesForKeysWithDictionary:dict];
// 遍历字典
[dict enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
NSLog(@"%@", key);
[self setValue:obj forKeyPath:key];
}];
具体步骤如下
- 1.根据遍历的key,到当前模型当中去找有没有跟当前key相同名称的
set方法
,如果有,就会调用该set方法
,给属性进行赋值。 - 2.如果没有
set方法
,还会去匹配有没有跟key值相同,并且还有下划线的成员属性_key,如果有,直接给下划线的成员属性赋值。 - 3.如果没有下划线的成员属性,还会去匹配有没有跟key值相同成员属性,如果有直接给该成员属性赋值,
- 4.如果还没有,就会调用当前模型setValue: forUndefinedKey:
- 5.如果还没有,直接报错
2、用处举例
我当前模型中有两个属性
@interface FLFlagM : NSObject
/** name*/
@property (copy, nonatomic) NSString *name;
/** icon*/
@property (copy, nonatomic) UIImage *icon;
-(instancetype)initWithDict:(NSDictionary *)dict;
+(instancetype)flagMWithDict:(NSDictionary *)dict;
@end
其中icon属性为图片名称,传入的字典是以字符串类型传入的,在正常情况下,我需要每次赋值时,使用[UIImage imageNamed:icon]
方法转换成对应的UIImage对象,这样会比较麻烦!
现在我们知道到setValuesForKeysWithDictionary:
方法内部实现原理,在方法遍历字典到了icon属性时,是直接调用icon的set方法来给该属性赋值的,我们就可以根据这一条,在icon的set方法中拦截赋值过程,直接做一次[UIImage imageNamed:icon]
转换即可,icon属性就直接以UIImage类型存放了,就可以直接把icon赋值给UIImageView了。