OC底层知识(三) : KVC

作者: IIronMan | 来源:发表于2018-06-19 14:58 被阅读66次
  • 1、KVC简单介绍

    • KVC的全称是Key-Value Coding,俗称“键值编码”,可以通过一个key来访问某个属性。KVC的基础知识
  • 2、常见的API

    - (id)valueForKeyPath:(NSString *)keyPath; // 最外层的属性赋值(带路径)
    - (id)valueForKey:(NSString *)key;  // 最外层的属性取值(带路径)
    - (void)setValue:(id)value forKeyPath:(NSString *)keyPath; // 其他层的属性赋值
    - (void)setValue:(id)value forKey:(NSString *)key; // 其他层的属性取值
    
  • 3、简单的使用

    • JKPerson继承于NSObject,JKDog继承于NSObject, 在JKPerson定义一个属性@property(nonatomic,strong) JKDog *dog;
    JKPerson *person = [[JKPerson alloc]init];
    [person setValue:@12 forKey:@"height"];
    person.dog = [[JKDog alloc]init];
    [person setValue:@20 forKeyPath:@"dog.age"];
    NSLog(@"height的值 ==== %@  dog.age ==== %@",[person valueForKey:@"height"],[person valueForKeyPath:@"dog.age"]);
    
  • 4、setValue:forKey(设置值):的原理


    setValue:forKey:->按照setKey:、_setKey:顺序查找方法
    • 找到方法:传递参数,调用方法
    • 没有找到方法:查看accessInstanceVariablesDirectly(能不能直接访问成员变量)方法的返回值
      • 返回YES(允许直接访问成员变量):按照_key_isKeykeyisKey顺序查找成员变量,找到了成员变量:直接赋值,没找到成员变量:调用setValue:forUndefinedKey:
        并抛出异常NSUnknownKeyException
      • 返回NO(不允许直接访问成员变量):调用setValue:forUndefinedKey:并抛出异常NSUnknownKeyException
  • 5、通过KVC修改属性会触发KVO吗?

    • 答案:会触发KVO
      KVC的内部会去调用KVO的监听方法
  • 6、KVC修改属性会触发KVO的底层原理是什么?

    WechatIMG73.jpeg
    JKObserve *jkObserve = [[JKObserve alloc]init];
    JKPerson *person = [[JKPerson alloc]init];
    [person addObserver:jkObserve forKeyPath:@"height" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew  context:NULL];
    [person setValue:@12 forKey:@"height"];
     /*
       [person willChangeValueForKey:@"height"]; // 将要改变height的值
       person -> _height; // 赋值
       [person didChangeValueForKey:@"height"];  // 调用KVO的监听方法
      */
     NSLog(@"height == %@",[person valueForKey:@"height"]);
     [person removeObserver:jkObserve forKeyPath:@"height"];
    
  • 7、valueForKey(取值):的原理?


    valueForKey:的原理图
     JKPerson *user = [[JKPerson alloc]init];
     user->_height = 10;
     NSLog(@"取出的值==%@", [user valueForKey:@"height"]);
    
    
     @interface JKPerson : NSObject
     {
        @public
        int height;
        int isHeight;
        int _isHeight;
        int _height;
     }
    
     -(int)getHeight{
         return 20;
     }
    
     -(int)height{
         return 21;
     }
    
     -(int)isHeight{
         return 22;
     }
    
     -(int)_height{
         return 23;
     }
    

    KVC底层练习的demo

相关文章

网友评论

本文标题:OC底层知识(三) : KVC

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