KVC和KVO

作者: 里克尔梅西 | 来源:发表于2018-04-10 21:13 被阅读14次

    一、KVC

    简介:key-value coding,顾名思义吧,即使可以通过属性名(key)来直接给属性值(value)来coding(赋值),这样可以省去调用setter和getter方法,从而简化代码。

    原理

    • 设值(setValue forKey)
      1、寻找setter的两个方法:setName 和 setIsName;
      2、如果setter的两个方法都没有,看+(BOOL)accessInstanceVariablesDirectly 这个方法的返回值方法的返回值,如果返回值为YES,则去找四个成员变量_name -> _isName -> name -> isName
      如果返回为NO,则去找valueForUndefinedKey,没有的话则会崩溃;
      3、如果我们给一个基本数据类型通过kvc设值,value给了一个nil,那么直接就会崩了,所以还有个异常处理方法来防治这个崩溃
    - (void)setNilValueForKey:(NSString *)key
    
    • 取值 (valueForKey)
      1、我们通过kvc的valueForKey:key方法去取值的时候,首先我们回去找getter的那三个方法
    - (NSString *)name;
    - (NSString *)getName;
    - (NSString *)isName;
    

    找到的话按照优先级得到值,这三个方法的优先级是:name,isName,getName;
    2、如果三个getter方法没有话的,kvc会继续找NSArray方法,就是- (NSInteger)countOfKey 和- (id)objectInKeyAtIndex:(NSInteger)index 他们两个,如果有的话就返回个数组;
    3、如果这两个NSArray方法也没有的话,我们会继续去找,继续去找+(BOOL)accessInstanceVariablesDirectly这个返回值为bool类型的方法,如果他的返回值是yes,那么我们就去找哪四个成员变量,_name _isName name isName也是按照优先级取值;
    4、如果+(BOOL)accessInstanceVariablesDirectly这个返回值为no的话,就不去找那四个成员变量了,回去找看有没有重载valueForUndefinedKey这个方法,按照要求重载了的话不会崩;
    5、kvc这个valueForKey:key会得到一个null值,如果没有重载这个方法,那么就会直接崩溃

    使用

    1、动态地取值和设值
    2、用KVC来访问和修改私有变量

    对于类里的私有属性,Objective-C是无法直接访问的,但是KVC是可以的

    3、Model和字典转换
    4、修改一些控件的内部属性
    5、用KVC中的函数操作集合

    KVC同时还提供了很复杂的函数,主要有下面这些
    ①简单集合运算符
    简单集合运算符共有@avg, @count , @max , @min ,@sum5种,都表示啥不用我说了吧, 目前还不支持自定义。

    ②对象运算符
    比集合运算符稍微复杂,能以数组的方式返回指定的内容,一共有两种:
    @distinctUnionOfObjects
    @unionOfObjects
    它们的返回值都是NSArray,区别是前者返回的元素都是唯一的,是去重以后的结果;后者返回的元素是全集。

    参考文章:
    https://www.jianshu.com/p/45cbd324ea65
    https://www.jianshu.com/p/3b3f206275a0(这里有自定义KVC的过程)
    https://www.jianshu.com/p/ee996fa2f2a4
    https://www.jianshu.com/p/1d39bc610a5b

    二、KVO

    简介:KVO是一种观察者模式的一种实现,与通知对应。指定一个被观察对象(例如类A),当A中的某个属性发生变化的时候,对象会获得通知,并作出相应的处理。

    原理

    KVO 的实现依赖于 Objective-C 强大的 Runtime。当观察对象A时,KVO机制动态创建一个新的名为:NSKVONotifying_A 的新类,该类继承自对象A的本类,且 KVO 为 NSKVONotifying_A 重写观察属性的 setter 方法,setter 方法会负责在调用原 setter 方法之前和之后,通知所有观察对象属性值的更改情况。被观察对象的 isa 指针从指向原来的 A 类,被 KVO 机制修改为指向系统新创建的子类 NSKVONotifying_A 类,来实现当前类属性值改变的监听。

    其他

    1、KVO与KVC的不同
    KVC(键值编码),即 Key-Value Coding,一个非正式的 Protocol,使用字符串(键)访问一个对象实例变量的机制。而不是通过调用 Setter、Getter 方法等显式的存取方式去访问。
    KVO(键值监听),即 Key-Value Observing,它提供一种机制,当指定的对象的属性被修改后,对象就会接受到通知。

    2、KVO与通知的区别
    notification比KVO多了一步发送通知;
    notifacation不止局限于属性的变化,还可以对状态进行监听,例如键盘,前后台等等。

    3、KVO与delegate的不同
    delegate一般是一对一,而KVO与notifacation是一对多;
    delegate需要通信的对象通过代理联系,需要返回值,而KVO则是发送接受通知,剩下的交由系统来做,不需要返回值。

    参考文章:
    https://www.jianshu.com/p/e59bb8f59302

    相关文章

      网友评论

          本文标题:KVC和KVO

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