• iOS之KVC字典转模型的底层实现


    KVC: Key Value Coding (键值编码)

    在iOS开发中,KVC是我们经常要使用的技术.那么KVC有什么作用呢?简单列举一下下面几种:

    • 取值和赋值(开发中基本不用)
    • 获取对象私有变量的值.(经常使用,例如UIPageContorl分页, 设置圆点为图片)
    • 改变对象私有变量的值(经常使用)
    • 简单的字典转模型(偶尔使用)
    • 模型转字典
    • 批量取值

    KVC字典转模型的底层实现

    • 通常我们手动将字典转模型的话,会在模型中提供一个类方法接收一个字典,在这个方法中将字典转换成模型,再将转换好的模型返回.

      + (instancetype)statusWithDict:(NSDictionary *)dict
      {
        Status *status = [[self alloc] init];
        //利用KVC字典转模型
        [status setValuesForKeysWithDictionary:dict];
      
        return status;
      }
    • 分析一下[status setValuesForKeysWithDictionary:dict]的底层实现原理

      + (instancetype)statusWithDict:(NSDictionary *)dict
      {
        Status *status = [[self alloc] init];
        //利用KVC字典转模型
        //[status setValuesForKeysWithDictionary:dict];
      
        //setValuesForKeysWithDictionary:原理--遍历字典中所有的key,去模型中查找对应的属性,把值给模型属性赋值
      
        [dict enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
            // 这行代码才是真正给模型的属性赋值
            [status setValue:obj forKey:key];
        }];
        return status;
      }
    • KVC字典转模型弊端:必须保证,模型中的属性和字典中的key一一对应。如果不是一一对应的话,就会报错,仔细看一下错误信息,[<Status 0x7fd439d20a60> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key source.是系统调用了setValue:forUndefinedKey:报错.如果想解决这个问题,只需要在模型中重写对象的setValue:forUndefinedKey:,把系统的方法覆盖, 就能继续使用KVC,字典转模型了。
      - (void)setValue:(id)value forUndefinedKey:(NSString *)key
      {
      }

    啰嗦一点KVC的setValue:forKey:方法赋值的原理

    • 首先会去模型中查找有没有对应key的setter方法,有就直接调用set方法方法赋值.
    • 上一步没有的话,去模型中查找有没有和key同名的属性,有的话赋值给与key同名的属性.
    • 上一步还没有的话,去属性中查找有没有和key同名的带下划线的属性,有的话直接赋值.
    • 如果再没有,那就直接调用对象的 setValue:forUndefinedKey:直接报错



    文/李小南(简书作者)
    原文链接:http://www.jianshu.com/p/a22ef43424f6
    著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
  • 相关阅读:
    蓝牙低功耗(Bluetooth Low Energy)
    Android 蓝牙(概述)
    Android 学习笔记之 Activity 简介
    Android 学习笔记之常用控件
    Android 学习笔记之界面布局
    委托和事件(C#)
    Java 资源汇总
    如何阅读英文原版教材
    Combobox 控件绑定数据
    《将博客搬至CSDN》
  • 原文地址:https://www.cnblogs.com/iOSJason/p/5559591.html
Copyright © 2020-2023  润新知