iOS 面试总结-kvo的底层实现(二)

作者: Figo_OU | 来源:发表于2019-07-09 19:24 被阅读35次

    1.kvo在底层是怎么实现的?

    在对象属性添加监听的时候。系统通过runtime,会创建一个派生类NSKVOVilifty_XXX的类。然后让该对象的isa指针,指向该派生类。派生类中重写了被监听属性的setter方法。setter方法中主要实现了一个c方法_NSSetIntValueAndNotify(int为对应的修改类型)。
    而_NSSetIntValueAndNotify方法主要实现了willChangeValueForKey:、父类的setter方法和didChangeValueForKey:方法。valueDidchange方法中会触发监听器(oberser)。

    2.“刚刚说到的派生类里面还实现了什么方法?”

    假设是监听的NSInteger age;
    实现了setAgeclass_isKvodealloc方法。

    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方法。

    相关文章

      网友评论

        本文标题:iOS 面试总结-kvo的底层实现(二)

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