IsKindOfClass and isMemberOfClass what is the difference between the underlying is how to implement, combined with the source code analysis is specifically how to implement.

isKindOfClass

IsKindOfClass implementation

If you look up isKindOfClass directly from the source code, you’ll find a class method, a class method, and an instance method. I should add that in ios 10.15 and ios13 and later, you won’t call isKindOfClass directly. You can see from assembly that objc_opt_isKindOfClass is called.

IsKindOfClass source code analysis

Next, isKindOfClass and objc_opt_isKindOfClass are analyzed.

+ (BOOL)isKindOfClass:(Class)cls { for (Class tcls = self->ISA(); tcls; tcls = tcls->getSuperclass()) { if (tcls == cls) return YES; } return NO; } - (BOOL)isKindOfClass:(Class)cls { for (Class tcls = [self class]; tcls; tcls = tcls->getSuperclass()) { if (tcls == cls) return YES; } return NO; } // 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); }Copy the code

IsKindOfClass’s class methods and instance methods are oc functions, and objc_opt_isKindOfClass is obviously c already.

  • IsKindOfClass process. Class metaclass vs CLS (classes that need to be compared), different continue to compare. The parent of the metaclass vs CLS, and comparisons continue until the root metaclass is found. Root metaclass vs CLS, different continue to compare. Root class NSObject vs CLS, if it’s not the same then the parent of root class NSObject is nil, breaks out of the loop and returns NO
  • IsKindOfClass process. Gets the current object’s class, class vs CLS, and continues to compare. Class parent vs CLS, and continue to compare until you find the root class (NSObject). Root class NSObject vs CLS, if it’s not the same then the parent of root class NSObject is nil, breaks out of the loop and returns NO

IsKindOfClass Case Study 1

#import <Foundation/Foundation.h>


@interface LQPeople : NSObject
@end
@implementation LQPeople
@end


int main(int argc, const char * argv[]) {
    @autoreleasepool {
        BOOL b1 = [NSObject isKindOfClass:NSObject.class];
        BOOL b2 = [LQPeople isKindOfClass:LQPeople.class];
        
        
        NSLog(@"%d %d",b1,b2);
    }
    return 0;
}

Copy the code

Analysis of the first cycle is obviously unequal

It’s equal by the second cycle

isMemberOfClass

IsMemberOfClass implementation

By looking up isKindOfClass directly from the source code, you can find a class method, a class method and an instance method. It is not certain that this will be optimized in the future. I haven’t found it yet.

+ (BOOL)isMemberOfClass:(Class)cls {
    return self->ISA() == cls;
}

- (BOOL)isMemberOfClass:(Class)cls {
    return [self class] == cls;
}
Copy the code
  • IsMemberOfClass process. Class metaclass vs CLS (the class to compare), return YES if the same, otherwise return NO
  • IsMemberOfClass process. Class vs CLS, return YES if they are the same, or NO if they are not

Compared to isKindOfClass, isMemberOfClass is relatively simple.