4:iOS 用什么方法实现对一个对象的kvo?(kvo本质)
利用runtimeAPI动态生成一个子类,并且让instance对象的isa指针指向这个全新的子类(NSKVONotifying_XXX)
当修改instance对象的属性时,会调用foundation的_NSSetXXXValueAndNotify函数
willChangeValueForKey
父类原来的setter
didChangeValueForKey
内部会触发监听器(Observe)的监听方法(observeValueForKeyPath:ofObject:change:context)
5:如何手动触发KVO
手动调用willChangeValueForKey 和 didChangeValueForKey
单纯调用didChangeValueForKey 是不会触发kvo的,因为这个方法的内部会去判断是否已经调用了willChangeValueForKey,如果没有调用是不会触发监听者的监听方法的
6:直接修改成员变量的会触发KVO么
不会触发KVO,因为KVO的本质是利用runtimeAPI动态生成一个子类,重写父类的setter方法,在新的setter方法里调用Foundation的_NSSetXXXValueAndNotify函数,直接修改成员变量的值,不会执行setter,所以不会触发kvo
kvo,kvc原理: https://www.cxymm.net/article/qq_32940999/104519398
7:通过kvc修改属性会触发kvo么?
会,因为setValue:forKey: 方法不一定会触发instance对象的setter方法,但是setValue:forKey:在更改成员变量值的时候,会手动调用willChangeValueForkey didChangeValueForKey 触发监听器回掉方法
8:KVC的赋值和取值过程是怎样的?原理是什么?
kvc setValue:forkey: 方法会按照setKey:,_setKey:顺序查找方法,如果没有找到,则查找accessInstanceVariablesDirectly的返回值,如果为NO,则抛出NSUnknowKeyExpection 异常,如果为YES,则按照_key,_isKey,key,iskey的顺序查找变量,如果找到了直接赋值,如果没找到,就抛出NSUnKnowKeyExpection异常
取值:valueForKey: 方法会按照getkey、key、isKey、_key顺序查找方法,如果没有找到,则查找accessInstanceVariablesDirectly的返回值,如果为NO,则抛出NSUnknowKeyExpection异常,如果为YES,则按照_key,_isKey,key,isKey的顺序查找成员变量,找到了直接取值,找不到直接抛出NSUnKnowKeyExpection 异常
网友评论