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
    著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
  • 相关阅读:
    PAT (Advanced Level) Practice 1055 The World's Richest (25 分) (结构体排序)
    PAT (Advanced Level) Practice 1036 Boys vs Girls (25 分)
    PAT (Advanced Level) Practice 1028 List Sorting (25 分) (自定义排序)
    PAT (Advanced Level) Practice 1035 Password (20 分)
    PAT (Advanced Level) Practice 1019 General Palindromic Number (20 分) (进制转换,回文数)
    PAT (Advanced Level) Practice 1120 Friend Numbers (20 分) (set)
    从零开始吧
    Python GUI编程(TKinter)(简易计算器)
    PAT 基础编程题目集 6-7 统计某类完全平方数 (20 分)
    PAT (Advanced Level) Practice 1152 Google Recruitment (20 分)
  • 原文地址:https://www.cnblogs.com/iOSJason/p/5559591.html
Copyright © 2011-2022 走看看