1.kvo在底层是怎么实现的?
在对象属性添加监听的时候。系统通过runtime,会创建一个派生类NSKVOVilifty_XXX的类。然后让该对象的isa指针,指向该派生类。派生类中重写了被监听属性的setter方法。setter方法中主要实现了一个c方法_NSSetIntValueAndNotify(int为对应的修改类型)。
而_NSSetIntValueAndNotify方法主要实现了willChangeValueForKey:、父类的setter方法和didChangeValueForKey:方法。valueDidchange方法中会触发监听器(oberser)。
2.“刚刚说到的派生类里面还实现了什么方法?”
假设是监听的NSInteger age;
实现了setAge
、class
、_isKvo
、dealloc
方法。
3.你是如何知道的这4个方法?
在对象的类对象中有方法列表,遍历方法列表打印看看就知道了。
- (void)printClassMethodNamesOfClass:(Class)cls{
unsigned int count;
//获得方法数组
Method *methodList = class_copyMethodList(cls, &count);
//遍历所有的方法
for(int i = 0; i < count; i++){
//获得方法
Method method = methodList[i];
//获得方法名
NSString *methodName = NSStringFromSelector(method_getName(method));
NSLog(@"方法名:%@ \n", methodName);
}
free(methodList);//C语言中copy出来的对象需要清空掉
}
4.系统是用什么类型来存放类对象的方法列表的?
存放方法列表的类型是Method_list_t,所以是一个数组。
5. 直接修改成员变量会触发KVO吗?
不会,KVO的本质是set方法,只有调用了set方法才会触发KVO。
6.那么用KVC去修改属性会触发KVO吗?
会的。
“为什么”。
额,kvc修改属性值的时候会调用setter方法,因为对象的isa指向派生类NSKVONotify_xxx,所以会由派生类的setter方法来相应这个setter方法。(懵,都说了set方法是本质了,还这么问)
7.如何手动触发KVO
手动调用willChangeValueForKey和didChangeValueForKey方法。
网友评论