KVC

作者: Chris_C | 来源:发表于2016-11-03 18:28 被阅读13次

    一、KVC

    KVC就是key-Value-coding,即键值编码,通常情况给某一个对象进行赋值。但是通常赋值操作直接使用点语法即可,简单方便,例如:

    Person *p = [[Person alloc]init];
    p.name = @"张三";
    p.age = 20;`
    

    我们也可以通过KVC给p赋值,代码如下,因为setValue这里的值是id类型的,所以将整数包装成一个对象,

    [p setValue:@"张三" forKey:@"name"];
    [p setValue:@20 forKey:@"age"];
    

    我们为什么不用点语法这样简单的操作进行赋值操作,而要使用KVC呢?
    比如Person类有一个私有属性,并且对外提供一个输出私有属性值的接口,例如:

    #import "Person.h"
    @impletation Person
    {
          NSInteger _height;
    }    
    
    - (void)logHeight
    {
         NSLog(@"%ld",_height);
    }
    

    这样的情况,我们在外部是无法直接给p设置身高的,外部无法访问到私有属性,但是有了KVC就不一样了。

    [p setValue:@170 forKey:@"height"];
    [p logHeight];
    

    我们在外部通过KVC直接对私有属性赋值,打印如下:

     2016-11-03 17:42:27.174 KVODemo[1246:41973] 170
    

    除了[p setValue:@170 forKey:@"height"]这个方法外,还有一个方法可以对私有属性赋值:
    [p setValue:@170 forKeyPath:@"height"]

    这两个方法对于普通的属性是没有区别的,都可以用,但是对一些特殊的属性就有区别了。
    比如说这个类又个属性是狗,狗又有属性体重:

    p.dog = [[Dog alloc] init];
    [p setValue:@200 forKey:@"dog.weight"];
    

    如果我们直接这样设置是会报错说找不到dog.weight,而在storyboard中,我们拖控件连线错误的时候报错也说找不到什么key,说明storyboard在赋值的时候也是通过KVC来操作的。

    但是,我们换另外一种方法,不会报错,而且可以打印出狗的体重。

    [p setValue:@200 forKeyPath:@"dog.weight"];
    

    说明forKeyPath是包含了forKey这个方法的功能的,甚至 forKeyPath方法还有它自己的高级功能,它会先去找有没有dog这个key,然后去找有没有weight这个属性。所以在使用KVC的时候,最好使用 forKeyPath这个方法。

    最后还有一点,代码如下:

    [p setValue:@170 forKey:@"height"];
    

    我们传入的字符串key是height,但是定义的属性是 _heigth,但是通过kvc还是可以给 _height属性赋到值。说明对某一属性进行赋值操作,可以不用加下划线,而且它的查找规则应该是:先查找与写入字符转相同的成员变量,如果找不到就找以下划线开头的成员变量。

    KVC除了访问私有变量的作用外,还可以用于字典转模型。在Person类对外提供一个接口,将转模型的工作放在模型中进行

    - (instancetype)initWithDict:(NSDictionary *)dict
    {
        if(self = [super init]) {
             [self setValueForKeysWithDictionary:dict];
          }
          return self;
    }
    
    kvc用法总结
    * 1.在外部对私有变量进行赋值
    * 2.字典转模型
    
    注意
    * 1.字典转模型的时候,字典的某一个key一定要在模型中有对应的属性
    * 2.如果模型中包含了另外的模型对象,是不能直接转化成功的。
    * 3.通过kvc转化模型中的模型,也是不能直接转换成功的。
    

    既然可以通过kvc赋值,也可以通过它取值:

    NSLog(@"name=%@",[p valueForKey:@"name"]);
    NSLog(@"dogWeight=%@",[p valueForKeyPath:@"p.dog"]);

    相关文章

      网友评论

        本文标题:KVC

        本文链接:https://www.haomeiwen.com/subject/gsciuttx.html