zoukankan      html  css  js  c++  java
  • 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
    著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
  • 相关阅读:
    Constants and Variables
    随想
    C#基础篇之语言和框架介绍
    Python基础19 实例方法 类方法 静态方法 私有变量 私有方法 属性
    Python基础18 实例变量 类变量 构造方法
    Python基础17 嵌套函数 函数类型和Lambda表达式 三大基础函数 filter() map() reduce()
    Python基础16 函数返回值 作用区域 生成器
    Python基础11 List插入,删除,替换和其他常用方法 insert() remove() pop() reverse() copy() clear() index() count()
    Python基础15 函数的定义 使用关键字参数调用 参数默认值 可变参数
    Python基础14 字典的创建修改访问和遍历 popitem() keys() values() items()
  • 原文地址:https://www.cnblogs.com/iOSJason/p/5559591.html
Copyright © 2011-2022 走看看