Swift教程

iOS-底层探索子类为什么可以通过类方法调用NSObject 中的实例方法

本文主要是介绍iOS-底层探索子类为什么可以通过类方法调用NSObject 中的实例方法,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

子类为什么可以通过类方法调用NSObject 中的实例方法

  1. 当我们在NSObject 中使用分类创建一个实例方法的时候,我们发现继承子NSObject的子类DNPerson 可以通过 类方法调用这个实例方法 这里涉及的知识点覆盖了方法查找流程整个查找过程是非常值得我们研究的,接下来让我们一起研究一下

准备工作

创建了一个继承自NSObject 的分类 ,其中主要有三个方法

  1. 一个实例方法,后续我们需要在找到这个方法到底被存在了哪里
  2. printMethods 输出当前class 的方法列表 打印方法名称
  3. 获取类、元类、根元类 以及根元类的superClass

.m文件中实现

创建NSObject子类DNPerson ,值得注意的是DNPerson中我们声明了3个方法,但是我们只实现了2个,那么没有实现的方法会存储在哪里呢?

方法查找流程解析:

问题本质其实是关于oc中对象数据存储的相关知识:

  • 实例对象的实例变量是存在实例对象里的
  • 实例方法是以实例存在实例对象isa指向的类对象里
  • 类方法是以实例存在类对象isa指向的元类对象里

isa 指向和Class的继承关系如下图所示:

代码堆栈信息解析

执行 [NSObject PrintClassChain: [DNPerson class]]; PrintClassChain ,中我们通过object_getClass 函数获取cls->ISA() 函数控制台打印如下

  • 我们可以看到DNPerson 中的 实例方法存储在元类的方法列表中,同时我们也可以发现@property也是相当于存储了一个set 以及一个get 的实例方法
  • 类方法dnTestClassMethod,存储在类元类方法列表中
  • 未实现的方法没有被存储

接下来我们来看下根元类中的方法打印信息

可以发现,根元类中只打印了类方法,此时根元类的class 为NSObject, 根元类superClass的方法列表打印如下

在这里我们发现了,NSObject 的实例方法,也就是说当我们在元类中查找方法直到根云类中也没有找到方法的时候会去NSObject 的类方法中查找一下,这也是为什么,继承NSObject 的子类可以执行通过类方法执行实例方法的原因

这篇关于iOS-底层探索子类为什么可以通过类方法调用NSObject 中的实例方法的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!