IsKindOfClass analysis

IsKindOfClass classification method and object method two.

  • Class methods: Compare a class to a metaclass
+ (BOOL)isKindOfClass:(Class) CLS {for (Class TCLS = self->ISA(); tcls; tcls = tcls->getSuperclass()) { if (tcls == cls) return YES; } return NO; }Copy the code
  • Object methods: Compare the current class to the class
- (BOOL)isKindOfClass:(Class) CLS {for (Class TCLS = [self Class]; tcls; tcls = tcls->getSuperclass()) { if (tcls == cls) return YES; } return NO; }Copy the code
BOOL re1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];       //
BOOL re2 = [(id)[JCPerson class] isKindOfClass:[JCPerson class]];       //
NSLog(@" re1 :%hhd\n re2 :%hhd\n",re1,re2,);

BOOL re3 = [(id)[NSObject alloc] isKindOfClass:[NSObject class]];       //
BOOL re4 = [(id)[JCPerson alloc] isKindOfClass:[JCPerson class]];       //
NSLog(@" re3 :%hhd\n re4 :%hhd\n",re3,re4);

Copy the code

The output is 1,0,1,1

Both the [NSObject class] class and the metaclass of NSObject are NSObject re1 is 1;

[JCPerson Class] is JCPerson, and the [JCPerson Class] metaclass is NSObject re2 is 0;

The class of the [NSObject alloc] object is NSObject, and the class of the [NSObject class] object is NSObject re3 is 1;

[JCPerson alloc] object class JCPerson, [JCPerson class] class JCPersonre4 is 1;

The pitfall is that when you compile the source code the isKindOfClass method doesn’t execute at all and instead goes to the following method objc_opt_isKindOfClass mainly because it was optimized for compilation in LLVM.

// Calls [obj isKindOfClass] BOOL objc_opt_isKindOfClass(id obj, Class otherClass) { #if __OBJC2__ if (slowpath(! obj)) return NO; Class cls = obj->getIsa(); // if obj is an object, isa isa class, // if obj isa class, isa isa metaclass if (fastpath(! CLS ->hasCustomCore())) {// if obj is an object, then compare in the Class inheritance chain, // if obj isa Class, then compare in the metaclass isa 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); }Copy the code
isMemberOfClass

Source analysis isMemberOfClass is divided into object methods and class methods

+ (BOOL)isMemberOfClass:(Class) CLS {return self->ISA() == CLS; - (BOOL)isMemberOfClass:(Class) CLS {return [self Class] == CLS; }Copy the code
BOOL re1 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];     //
BOOL re2 = [(id)[JCPerson class] isMemberOfClass:[JCPerson class]];     //
BOOL re3 = [(id)[NSObject alloc] isMemberOfClass:[NSObject class]];     //
BOOL re4 = [(id)[JCPerson alloc] isMemberOfClass:[JCPerson class]];     //
NSLog(@" re1 :%hhd\n re2 :%hhd\n re3 :%hhd\n re4 :%hhd\n",re1,re2,re3,re4);
Copy the code

The output is 0,0,1,1