iOS之class方法和object_getClass方法的区别

本文详细分析了Objective-C中class方法与object_getClass方法的区别,包括实例对象、类对象、元类对象等不同情况下的行为。同时,文章还总结了isa和superclass在类继承结构中的作用,阐述了对象方法和类方法的调用轨迹。
摘要由CSDN通过智能技术生成

一、源码分析

// 类方法 返回自身
+ (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()) return ISA();

    uintptr_t ptr = (uintptr_t)this;
    if (isExtTaggedPointer()) {
        uintptr_t slot = 
            (ptr >> _OBJC_TAG_EXT_SLOT_SHIFT) & _OBJC_TAG_EXT_SLOT_MASK;
        return objc_tag_ext_classes[slot];
    } else {
        uintptr_t slot = 
            (ptr >> _OBJC_TAG_SLOT_SHIFT) & _OBJC_TAG_SLOT_MASK;
        return objc_tag_classes[slot];
    }
}

// 判断是否TaggedPointer
inline bool 
objc_object::isTaggedPointer() 
{
    return _objc_isTaggedPointer(this);
}

static inline bool 
_objc_isTaggedPointer(const void * _Nullable ptr) 
{
    return ((uintptr_t)ptr & _OBJC_TAG_MASK) == _OBJC_TAG_MASK;
}

inline bool 
objc_object::isExtTaggedPointer() 
{
    return ((uintptr_t)this & _OBJC_TAG_EXT_MASK) == _OBJC_TAG_EXT_MASK;
}
class方法和object_getClass方法的区别
1、当objc是实例对象时
  • [obj class] 和 object_getClass(obj) 返回的结果是一样的。结果是isa的所指向的对象,即指向类对象。
Person *person = [Person new];
    NSLog(@"---person---%@---%@",[person class],object_getClass(person));

在这里插入图片描述

2、 当obj是class类对象时
  • object_getClass(obj)返回类对象中的isa指向的元类对象,即指向元类对象
  • [obj class]返回类对象本身
3、当obj为Metaclass类对象时
  • [obj class]返回元类本身
  • object_getClass(obj)返回元类对象中的isa指向的根元类,即指向根元类
4、当obj为Rootclass类对象
  • [obj class]返回本身
  • object_getClass(obj)返回元类对象中的isa指向的根元类,即指向根元类
5、当obj为Rootmetaclass类对象
  • [obj class]返回本身
  • object_getClass(obj) 返回自身

如有不理解可以看下图:
在这里插入图片描述

二、 isa、superclass总结

  • instance的isa指向class
  • class的isa指向meta-class
  • meta-class的isa指向基类的meta-class
  • class的superclass指向父类的class
    • 如果没有父类,superclass指针为nil
  • meta-class的superclass指向父类的meta-class
    • 基类的meta-class的superclass指向基类的class
  • instance调用对象方法的轨迹
    • isa找到class,方法不存在,就通过superclass找父类
  • class调用类方法的轨迹
    • isa找meta-class,方法不存在,就通过superclass找父类
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值