KVC的内部实现

1、kvc的常用方法

- (nullable id)valueForKeyPath:(NSString *)keyPath;
- (void)setValue:(nullable id)value forKeyPath:(NSString *)keyPath;

- (void)setValuesForKeysWithDictionary:(NSDictionary *)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了。

你可能感兴趣的:(KVC的内部实现)