KVC和KVO

一、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)