class / superClass / object_getClass isKindOfClass/isMemberOfClass 详解

1. objc_getClass

通过类名来获取一个类对象,传入 const char * 返回对应的类对象。

  • 源码
/***********************************************************************
* objc_getClass.  Return the id of the named class.  If the class does
* not exist, call _objc_classLoader and then objc_classHandler, either of 
* which may create a new class.
* Warning: doesn't work if aClassName is the name of a posed-for class's isa!
**********************************************************************/
Class objc_getClass(const char *aClassName)
{
    if (!aClassName) return Nil;

    // NO unconnected, YES class handler
    return look_up_class(aClassName, NO, YES);
}

示例:

  Class c1 = objc_getClass((const char *)"NSObject");
  Class c2 = objc_getClass((const char *)"NSObject"
  Class c3 = [NSObject class];
                
  NSObject *ojb = [[c1 alloc] init];

  NSLog(@"%p, %p, %p", c1, c2 , c3 );
  //0x7fff94d1c118, 0x7fff94d1c118, 0x7fff94d1c118
  NSLog(@"%p",  ojb );
  //0x10071c950

2. class、supperClass

实例对象、类对象调用class方法都返回类对象

- (Class)class {
    //self->isa
    return object_getClass(self);
}
    /*
     *  objc_msgSendSuper 的消息接受者仍然是self,只是从父类开始查找方法的实现,class最终再NSObject中找到。调用者仍然是self。
     * [super message]的底层实现
   * 1.消息接收者仍然是子类对象
     * 2.从父类开始查找方法的实现
     *  最终调用的其实是 [self messges]
     * 3. class方法最终再NSObject中找到,调用者仍然是self,所以[super class]仍然打印MJStudent
     */
- (Class)superclass
{
    return class_getSuperclass(object_getClass(self));
}

+ (Class)class {

    return self;
}

示例:

NSObject *object1 = [[NSObject alloc] init];
Class object2 = object_getClass(object1);
// 0x7fff94d1c118 0x7fff94d1c118 0x7fff94d1c118
NSLog(@"%p %p %p",[NSObject class], [object1 class], [object2 class]);

3. object_getClass

传入一个对象,获取该对象isa指针指向的对象

  • 源码
Class object_getClass(id obj)

{
    if (obj) return obj->getIsa();
    else return Nil;
}

如果传入的是 实例对象instance,则返回 类对象class
如果传入的是 类对象class,则返回 元类对象meta-class,
如果传入的是 元类对象meta-class,则返回NSObject(基类)的元类对象meta-class

示例:

        NSObject *instanceClass = [[NSObject alloc] init];
        Class classObj = object_getClass(instanceClass);
        Class metaclassObj = object_getClass(classObj);
        
        NSLog(@"%p %p %p",instanceClass, classObj, metaclassObj);
      //0x100743440 0x7fff94d1c118 0x7fff94d1c0f0
      
        NSLog(@"%p ", [NSObject class]);//0x7fff94d1c118

        bool isMeta = class_isMetaClass(metaclassObj);
        NSLog(@"metaclassObj : %d ", isMeta);// 1

4 isKindOfClass 与 isMemberOfClass 区别

  • 如果是实例对象
    -isMemberOfClass:表示该调用者是否是传入类的实例对象。
    -isKindOfClass:表示该调用者是否是传入类或其子类的实例对象。
- (BOOL)isMemberOfClass:(Class)cls {
    return [self class] == cls;
}

- (BOOL)isKindOfClass:(Class)cls {
    for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {
        if (tcls == cls) return YES;
    }
    return NO;
}
  • 如果是类对象
    +isMemberOfClass:表示该调用者isa指针所指对象 与 传入的对象是否一致。
    +isKindOfClass:表示该调用者isa指针所指对象 与 传入类或其子类是否一致。
+ (BOOL)isMemberOfClass:(Class)cls {
    return object_getClass((id)self) == cls;
}

+ (BOOL)isKindOfClass:(Class)cls {
    for (Class tcls = object_getClass((id)self); tcls; tcls = tcls->superclass) {
        if (tcls == cls) return YES;
    }
    return NO;
}
5 实例分析
@interface LXPerson : NSObject
@end

@interface LXStudent : LXPerson
@end

分析以下结果:

@implementation LXStudent

- (instancetype)init
{
    self = [super init];
    if (self) {
        NSLog(@"%@",[self class]);
        NSLog(@"%@",[self superclass]);
        NSLog(@"%@",[super class]);
        NSLog(@"%@",[super superclass]);

    }
    return self;
}

//LXStudent LXPerson LXStudent  LXPerson

    BOOL res11 = [[LXStudent new] isKindOfClass: [LXStudent class]];
    BOOL res12 = [[LXStudent new] isMemberOfClass: [LXStudent class]];

    BOOL res21 = [[LXStudent new] isKindOfClass: [NSObject class]];
    BOOL res22 = [[LXStudent new] isMemberOfClass: [NSObject class]];
    /* YES YES YES NO*/
    
    BOOL res31 = [[NSObject class] isKindOfClass:[NSObject class]];
    BOOL res32 = [[NSObject class] isMemberOfClass:[NSObject class]];
    BOOL res33 = [[NSObject class] isMemberOfClass:object_getClass([NSObject class])];
    /* YES NO YES*/
    
    BOOL res41 = [[LXPerson class] isKindOfClass:[LXPerson class]];
    BOOL res42 = [[LXPerson class] isKindOfClass:[NSObject class]];
    BOOL res43 = [[LXPerson class] isKindOfClass:object_getClass([LXPerson class])];
    /* NO YES YES*/

    BOOL res44 = [[LXPerson class] isMemberOfClass:[LXPerson class]];
    BOOL res45 = [[LXPerson class] isMemberOfClass:[NSObject class]];
    BOOL res46 = [[LXPerson class] isMemberOfClass:object_getClass([LXPerson class])];
    /*  NO  NO YES */
image.png

你可能感兴趣的:(class / superClass / object_getClass isKindOfClass/isMemberOfClass 详解)