zoukankan      html  css  js  c++  java
  • KVC、KVO 理解

    参考经典链接:

    https://www.jianshu.com/p/f8198ca5e682

    https://www.jianshu.com/p/be80318115a7

     

    一. KVC

    1.KVC介绍

    KVC 就是键值编码(key-value-coding)。

    2.KVC 的主要作用:

    (1)通过键值路径为对象的属性赋值。主要是可以为私有的属性赋值。

    AppleViewController *appleVC = [[AppleViewController alloc]init];
    [appleVC setValue:@"橘子" forKey:@"name"];

    如果对象A的属性是一个对象B,要设置对象B的属性

    [person setValue:@"旺财" forKeyPath:@"dog.name"];

    (2)通过键值路径获取属性的值。主要是可以通过key获得私有属性的值。

    NSString *nameStr = [appleVC valueForKey:@"name"];
     
    也可以通过keypath获得值

    NSString *dName = [person valueForKeyPath:@"dog.name"];

    (3)将字典转型成Model,方法:setValuesForKeysWithDictionary:

    复制代码
    // 定义一个字典
    NSDictionary *dict = @{
    @"name" : @"jack",
    @"money" : @"20.7",
    };
    // 创建模型
    Person *p = [[Person alloc] init];

    // 字典转模型
    [p setValuesForKeysWithDictionary:dict];
    NSLog(@"person's name is the %@",p.name);
    复制代码
    注意:字典的key和Model的属性一定要一一对应。否则会出现错误。比如person里没有name的属性,系统报错如下:

    '[<Person 0x60000001d0b0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key name.'

    二. KVO

    1.KVO介绍:

    KVO 是键值观察者(key-value-observing)。KVO提供了一种观察者的机制,通过对某个对象的某个属性添加观察者,当该属性改变,就会调用"observeValueForKeyPath:"方法,为我们提供一个“对象值改变了!”的时机进行一些操作。

    2.KVO原理

      当某个类的对象第一次被观察时,系统在运行时会创建该类的派生类,改派生类中重写了该对象的setter方法,并且在setter方法中实现了通知的机制。派生类重写了class方法,以“欺骗”外部调用者他就是原先那个类。系统将这个类的isa指针指向新的派生类,因此改对象也就是新的派生类的对象了。因而改对象调用setter就会调用重写的setter,从而激活键值通知机制。此外派生类还重写了delloc方法来释放资源。

    3.KVO的使用

    (1)给对象的属性添加观察者  

    [appleVC addObserver:self forKeyPath:@"name" options: NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:NULL];
    注: options: NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld 返回未改变之前的值和改变之后的值 context可以为空

      (2)若该属性发生改变,系统自动调用下面的方法:

    复制代码
    -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
    {
    //拿到新值/旧值,进行操作
    NSLog(@"newValue----%@",change[@"new"]);
    NSLog(@"oldValue----%@",change[@"old"]);

    }
    复制代码
      (3)取消监听

    -(void)dealloc
    {
    [person removeObserver:self forKeyPath:@"test"];
    }
    4.KVO的使用场景

    KVO用于监听对象属性的改变。

      (1)下拉刷新、下拉加载监听UIScrollView的contentoffsize;
      (2)webview混排监听contentsize;
      (3)监听模型属性实时更新UI;
      (4)监听控制器frame改变,实现抽屉效果。

      KVC修改属性,一定是会出发KVO的,这个我们用代码可以很容易的得到实验结果。因为setValue:forKey会按照setKey:、_setKey:顺序查找方法,如果找到方法,传递参数调用方法,如果没有找到方法,查看accessInstanceVariableDirectly方法的返回值,返回YES按照_key、_isKey、key、iskey顺序查找成员变量,找到的话直接赋值。如果返回NO,调用setValue:forUndefinedKey:并抛出异常NSUnknownKeyException


     

  • 相关阅读:
    8月10日
    8月9日
    8月8日
    8月7日
    8月6日
    8月5日
    《大道至简》读后感
    8月4日
    8月3日
    8月2日
  • 原文地址:https://www.cnblogs.com/xujinzhong/p/11155080.html
Copyright © 2011-2022 走看看