美文网首页
iOS 内省的几个方法

iOS 内省的几个方法

作者: 一个半吊子工程师 | 来源:发表于2020-09-29 18:48 被阅读0次

    什么是内省?

    在计算机科学中,内省是指计算机程序在运行时(Run time)检查对象(Object)类型的一种能力,通常也可以称作运行时类型检查。 不应该将内省和反射混淆。
    相对于内省,反射更进一步,是指计算机程序在运行时(Run time)可以访问、检测和修改它本身状态或行为的一种能力。

    内省的几个方法

    isMemberOfClass //对象是否是某个类型的 对象

    isMemberOfClass的源码实现是拿到自己的isa指针和自己比较,是否相等。

    isKindOfClass //对象是否是某个类型或某个类型子类的 对象

    • (BOOL)isKindOfClass:(Class)cls方法内部,会先去获得object_getClass的类,而object_getClass的源码实现是去调用当前类的obj->getIsa(),最后在ISA()方法中获得meta class的指针。

    isSubclassOfClass//某个类对象 是否是另一个类型的子类
    isAncestorOfObject //某个类对象 是否是另一个类型的父类
    respondsToSelector //是否能响应某个方法
    conformsToProtocol //是否遵循某个协议

    isKindOfClass 与 isMemberOfClass

    @interface Sark : NSObject
     @end
     
     @implementation Sark
     @end
     
     int main(int argc, const char * argv[]) {
    @autoreleasepool {
        BOOL res1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];
        BOOL res2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];
        BOOL res3 = [(id)[Sark class] isKindOfClass:[Sark class]];
        BOOL res4 = [(id)[Sark class] isMemberOfClass:[Sark class]];
     
       NSLog(@"%d %d %d %d", res1, res2, res3, res4);
    }
    return 0;
    }
    
    //1 0 0 0
    

    在isKindOfClass中有一个循环,先判断class是否等于meta class,不等就继续循环判断是否等于super class,不等再继续取super class,如此循环下去。

    接着也要用到这么一张图


    • [NSObject class]执行完之后调用isKindOfClass,第一次判断先判断NSObject 和 NSObject的meta class是否相等,之前讲到meta class的时候放了一张很详细的图,从图上我们也可以看出,NSObject的meta class与本身不等。

    • 接着第二次循环判断NSObject与meta class的superclass是否相等。还是从那张图上面我们可以看到:Root class(meta) 的superclass 就是 Root class(class),也就是NSObject本身。所以第二次循环相等,于是第一行res1输出应该为YES。

    • 同理,[Sark class]执行完之后调用isKindOfClass,第一次for循环,SarkMeta Class[Sark class]不等,第二次for循环Sark Meta Class的super class 指向的是 NSObject Meta Class, 和 Sark Class不相等。

    • 第三次for循环,NSObject Meta Classsuper class指向的是NSObject Class,和 Sark Class 不相等。第四次循环,NSObject Classsuper class 指向 nil, 和 Sark Class不相等。第四次循环之后,退出循环,所以第三行的res3输出为NO

    • 如果把这里的Sark改成它的实例对象,[sark isKindOfClass:[Sark class],那么此时就应该输出YES了。因为在isKindOfClass函数中,判断sark的meta class是自己的元类Sark,第一次for循环就能输出YES了。

    • isMemberOfClass的源码实现是拿到自己的isa指针和自己比较,是否相等。

    • 第二行isa 指向 NSObjectMeta Class,所以和 NSObject Class不相等。第四行,isa指向SarkMeta Class,和Sark Class也不等,所以第二行res2和第四行res4都输出NO。

    相关文章

      网友评论

          本文标题:iOS 内省的几个方法

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