- 经典面试题 :isKindOfClass 和 isMemberOfClass

790 阅读1分钟

BOOL re1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];       //
BOOL re2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];     //
BOOL re3 = [(id)[LGPerson class] isKindOfClass:[LGPerson class]];       //
BOOL re4 = [(id)[LGPerson class] isMemberOfClass:[LGPerson class]];     //
NSLog(@" re1 :%hhd\n re2 :%hhd\n re3 :%hhd\n re4 :%hhd\n",re1,re2,re3,re4);

BOOL re5 = [(id)[NSObject alloc] isKindOfClass:[NSObject class]];       //
BOOL re6 = [(id)[NSObject alloc] isMemberOfClass:[NSObject class]];     //
BOOL re7 = [(id)[LGPerson alloc] isKindOfClass:[LGPerson class]];       //
BOOL re8 = [(id)[LGPerson alloc] isMemberOfClass:[LGPerson class]];

isKindOfClass

  • 1.打开汇编指令编译器,打上断点运行

image.png

  • 2.发现真实调用的方法是 objc_opt_isKindOfClass image.png
// Calls [obj isKindOfClass]
BOOL
objc_opt_isKindOfClass(id obj, Class otherClass)
{
#if __OBJC2__
    if (slowpath(!obj)) return NO;
    Class cls = obj->getIsa();
    if (fastpath(!cls->hasCustomCore())) {
        for (Class tcls = cls; tcls; tcls = tcls->getSuperclass()) {
            if (tcls == otherClass) return YES;
        }
        return NO;
    }
#endif
    return ((BOOL(*)(id, SEL, Class))objc_msgSend)(obj, @selector(isKindOfClass:), otherClass);
}

-1.取出当来对象的 isa 指向的类或元类,
-2.将等到的类或元类的父类取出
-3.与传入的 otherClass 做对比
-------
- 1.[NSObject Class]MetaClasssuperClass[ NSObjct Class] 结果为1
    - 1.第一次循环获取isa 的结果 是MetaClass 对比 RootClassNO,但是循环没有结束
    - 2.MetaClassSuperClass 的结果是 RootClass 对比结果 是 YES
- 2.[LGPerson class]MetaClassLGPerson(Meta) 的 superClassRootClass(meta),然后对比 [LGPerson Class]
    - 1.第一次结果为0- 2.再一次循环后RootClass(meta)的superClass[NSObject Class] 结果为 0
    - 3. [NSObjct class]superClassnil 结果为0   
- 3. 57 的结果自然就是YES    

isMemberOfClass

image.png

  • 类方法获取他的元类、对象方法获取类。然后对比 image.png

  • 2、4 是获取的元类与类对比为NO

  • 6、8 是获取了类与类对比为YES