文章目录
一、源码分析
// 类方法 返回自身
+ (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找父类