子类为什么可以通过类方法调用NSObject 中的实例方法
- 当我们在NSObject 中使用分类创建一个实例方法的时候,我们发现继承子NSObject的子类DNPerson 可以通过 类方法调用这个实例方法 这里涉及的知识点覆盖了方法查找流程整个查找过程是非常值得我们研究的,接下来让我们一起研究一下
准备工作
创建了一个继承自NSObject 的分类 ,其中主要有三个方法
- 一个实例方法,后续我们需要在找到这个方法到底被存在了哪里
- printMethods 输出当前class 的方法列表 打印方法名称
- 获取类、元类、根元类 以及根元类的superClass
.m文件中实现
方法查找流程解析:
问题本质其实是关于oc中对象数据存储的相关知识:
- 实例对象的实例变量是存在实例对象里的
- 实例方法是以实例存在实例对象isa指向的类对象里
- 类方法是以实例存在类对象isa指向的元类对象里
isa 指向和Class的继承关系如下图所示:
代码堆栈信息解析
执行 [NSObject PrintClassChain: [DNPerson class]]; PrintClassChain ,中我们通过object_getClass 函数获取cls->ISA() 函数控制台打印如下
- 我们可以看到DNPerson 中的 实例方法存储在元类的方法列表中,同时我们也可以发现@property也是相当于存储了一个set 以及一个get 的实例方法
- 类方法dnTestClassMethod,存储在类元类方法列表中
- 未实现的方法没有被存储
接下来我们来看下根元类中的方法打印信息