文章目录
OC对象 - isa指针和supperClass
1. isa指针
1.1 isa指针分别指向哪里
1.1.1 instance的isa指针指向class
- 当调用
对象方法
时,通过instance
的isa
找到class
,最后找到对象方法
的实现进行调用
1.1.2 class的isa指向meta-class
- 当调用
类方法
时,通过class
的isa
找到meta-class
,最后找到类方法
的实现进行调用
1.2 代码验证isa地址
64位开始,isa需要进行一次位运算,才能计算出真实地址 掩码:
ISA_MASK
1.2.1 掩码
- arm64:0x0000000ffffffff8
- x86_64: 0x00007ffffffffff8
1.2.2 位运算结果
因为我的电脑是M系列芯片,是arm64架构,所以使用掩码0x0000000ffffffff8
- 如图,可以看到isa & ISA_MASK 后,跟 personClass 的地址是一样的
2. supperClass
2.1 class对象的supperClass指针
- 当Studen的
instance
对象要调用Person的对象方法时
,会先通过isa
找到 Studen 的class
,然后通过supperclass
找到 Person 的class
,最后找到对象方法
的实现进行调用
2.2 meta-class元类对象的supperClass指针
- 当Studen的
class
要调用Person的类方法
时,会先通过isa
找到 Studen 的meta-class
,然后通过supperclass
找到 Person 的meta-class
,最后找到类方法
的实现进行调用
3. isa、supperclass总结
3.1 instance的isa指向class
3.2 class的isa指向meta-class
3.3 meta-class的isa指向基类的meta-class
3.4 class的supperclass指向父类的class
- 如果没有父类,supperclass指针位nil
3.5 meta-class的supperclass指向父类的meta-class
- 基类的meta-class的supperclass指向基类的class
3.6 instance调用对象方法的轨迹
- isa找到class,方法不存在,就通过supperclass找父类
3.7 class调用类方法的轨迹
- isa找meta-class,方法不存在,就通过supperclass找父类meta-class
4. 针对3.5标红的情况
- 根类的元类对象找不到方法,会到类对象继续找,再找不到才抛出异常
4.1 验证
- 首先我们创建一个NSObject的分类,给NSObject增加一个实例方法
@interface NSObject (Test)
- (void)test;
@end
@implementation NSObject (Test)
- (void)test {
NSLog(@"-[NSObject class] - %p", self.class);
}
@end
- 然背使用 NSObject 类对象调用 text 方法
int main(int argc, const char * argv[]) {
@autoreleasepool {
// 打印 NSObject 类对象
NSLog(@"[NSObject class] - %p", NSObject.class);
// 使用 NSObject 类对象调用 test 方法
[NSObject test];
}
return 0;
}
- 打印如下,我们看到调用的是类方法,实际是执行到实例方法
- objc_msgSend 方法 ,只知道传入的方法名,不知道是实例方法还是类方法
4. 窥探struct objc_class的的结构
4.1 源码
- 源码中查找
struct objc_class
,: objc_object
代表C++结构体的继承
- 我们继续找
struct objc_object
,它里面就是isa
一个成员
- 所以它的结构就是
@oubijiexi