class方法和objc_getClass方法

626 阅读2分钟

objc_getClass示例

image.png

void lgTestNSObject(){
    // NSObject实例对象
    NSObject *object1 = [NSObject alloc];
    // NSObject类
    Class class = object_getClass(object1);
    // NSObject元类
    Class metaClass = object_getClass(class);
    // NSObject根元类
    Class rootMetaClass = object_getClass(metaClass);
    // NSObject根根元类
    Class rootRootMetaClass = object_getClass(rootMetaClass);
    NSLog(@"\n%p 实例对象\n%p 类\n%p 元类\n%p 根元类\n%p 根根元类",object1,class,metaClass,rootMetaClass,rootRootMetaClass);
}

objc_getClass方法结论

image.png 如上图所示,object_getClass返回内容沿isa指向。

class方法和objc_getClass方法示例

image.png

//LGPerson继承自NSObject
void lgTestClassNum(){
    //参数为实例对象
    Class class1 = object_getClass([LGPerson alloc]); //返回类 LGPerson
    Class class2 = [LGPerson alloc].class;      //返回类 LGPerson
    //参数为类
    Class class3 = object_getClass([LGPerson class]); //返回元类 LGPerson
    Class class4 = [LGPerson class];            //类方法返回调用者本身 返回类对象本身 LGPerson
    //参数为元类
    Class class5 = object_getClass(class3);     //返回根元类 NSObject
    Class class6 = [object_getClass([LGPerson class]) class];    //返回元类对象本身 LGPerson
    //参数为根元类(NSObject)
    Class class7 = object_getClass(class5);     //返回根元类 NSObject
    Class class8 = [object_getClass(class3) class];
    NSLog(@"\n class1-%p-%@\n class2-%p-%@\n class3-%p-%@\n class4-%p-%@\n class5-%p-%@\n class6-%p-%@\n class7-%p-%@\n class8-%p-%@\n",class1,class1,class2,class2,class3,class3,class4,class4,class5,class5,class6,class6,class7,class7,class8,class8);
}

class方法和objc_getClass方法源码

/// 类方法,返回自身
+ (Class)class {
    return self;
}


/// 实例方法,查找isa(类)
- (Class)class {
    return object_getClass(self);
}

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

inline Class
objc_object::getIsa()
{
    if (isTaggedPointer()) {
        uintptr_t slot = ((uintptr_t)this >> TAG_SLOT_SHIFT) & TAG_SLOT_MASK;
        return objc_tag_classes[slot];
    }
    return ISA();
}

inline Class
objc_object::ISA()
{
    assert(!isTaggedPointer());
    return (Class)(isa.bits & ISA_MASK);
} 

结论说明

  • 当参数objObject实例对象:例如[LGPerson alloc]

    • object_getClass(obj)与obj调用实例方法- (Class)class输出结果相同,均获得isa指针,即指向类对象的指针。
  • 当参数objClass类对象 例如LGPerson

    • object_getClass(obj)返回类对象中的isa指针,即指向元类对象的指针;
    • [obj class]调用类+ (Class)class方法,返回类对象本身。
  • 当参数objMetaclass元类对象 元类对象

    • object_getClass(obj)返回元类对象中的isa指针,因为元类对象的isa指针指向根元类NSObject,所以返回的是根元类对象的地址指针;
    • [obj class]调用类+ (Class)class方法,返回调用者元类本身。
  • 当参数objRootclass根元类对象 根元类对象NSObject

    • object_getClass(obj)返回根类对象中的isa指针,因为根元类对象的isa指针指向Rootclass‘s metaclass(根元类),即返回的是根元类的地址指针;
    • [obj class]调用类+ (Class)class方法,返回调用者根元类本身。

总结

  • object_getClass(obj)

    • 返回的是obj的isa指针;
  •  [obj class]

    • obj为实例对象 例如person。调用的是实例方法- (Class)class,返回的obj对象中的isa指针;
    • obj为类对象(包括元类、和根类(根元类)) 例如LGPerson(LGPerson、LGPerson、NSObject),调用的是类方法:+ (Class)class,返回的结果为 调用者本身。

参考