KVO全称(Key-Value Observing)键值监听,用于监听某个对象属性值的变化。
1、iOS用什么方式实现对一个对象的KVO (KVO的本质是什么)?
答: 当给一个instance对象的某个属性添加KVO时,系统会利用Runtime API动态生成一个子类,并让instance对象的isa指向这个全新的子类。当修改instance对象的属性值时,会调用Foundation的_NSSetXXXValueAndNotify函数,函数中的实现流程是:
调用willchangevalueforkey
调用父类原来的setter方法
调用didchangevalueforkey
内部会触发监听器(observe)的监听方法 observevalueforkeypath:ofobject:change:context:
2、如何手动触发KVO?
答:手动调用willchangevalueforkey 、didchangevalueforkey
3、直接修改成员变量的值,会不会触发KVO?
答:不会,KVO的本质是生成一个子类,重写父类的setter方法,在新的setter方法里面调用Foundation的_NSSetXXXValueAndNotify函数,直接修改成员变量的值,不会执行setter,所以不会触发KVO。
KVC全称Key-Value-Code,俗称“键值编码”,可以同意一个key来访问某个属性。
4、KVC的赋值和取值过程是什么样的,原理是什么?
答:KVC setValue:forkey:方法会按照setKey:、_setKey:顺序查找方法,如果没找到,则查找accessInstanceVariablesDirectly(是否可以直接访问成员变量,默认为YES)的返回值,如果为NO,则抛出NSUnknowKeyExpection异常,如果为YES,则按照_key、_isKey、key、isKey的顺序查找成员变量,找到了就直接赋值,找不到的话,就抛出NSUnknowKeyExpection异常。
valueForKey:方法会按照getkey、_key、 isKey、_key顺序查找方法,如果没找到,则查找accessInstanceVariablesDirectly的返回值,如果为NO,则抛出NSUnknowKeyExpection异常,如果为YES,则按照_key、_isKey、key、isKey的顺序查找成员变量,找到了就直接取值,找不到的话,就抛出NSUnknowKeyExpection异常。
4、KVC修改属性会触发KVO吗?
答:会的 ,尽管setvalue:forkey:方法不一定会触发instance实例对象的setter:方法,但是setvalue:forkey:在更改成员变量值的时候,会手动调用willchangevalueforkey、didchangevalueforkey,触发监听器的回调方法。