注:class 对象和 meta-class 对象都是 Class 类型的,它们其实结构都是一样的,class对象中一样会包含 类方法,只不过那个类方法是 空的而已。
同样,meta-class对象中也有 类的属性、对象方法、协议、成员变量,不过那些对应的值也都是空
isa指针
上面我们通过源码可以看到每个对象都有一个 isa 指针,isa指针作用是干嘛的呢?
通过上图可以看出:
1> instance的isa指向class
当调用对象方法时,通过instance的isa找到class,最后找到对象方法的实现进行调用
2> class的isa指向meta-class
当调用类方法时,通过class的isa找到meta-class,最后找到类方法的实现进行调用
class对象的superclass指针
superclass是用于找父类的,比如子类调用某个方法,如果子类中没有,就会去父类找,底层就是通过superclass找到父类的,如下图:
当Student的instance对象要调用Person的对象方法时,会先通过isa找到Student的class,然后通过superclass找到Person的class,最后找到对象方法的实现进行调用
meta-class对象的superclass指针
meta-class中的superclass基本和 class对象中的一样,不过有一点点区别,如图:
当Student的class要调用Person的类方法时,会先通过isa找到Student的meta-class,然后通过superclass找到Person的meta-class,最后找到类方法的实现进行调用
有什么区别呢?从这图可能看不出来,区别就是如果基类的meta-class中都找不到类方法,那么它就会去从基类对象里面去找对象方法,OC的底层其实是不区分 对象方法与类方法的。
isa、superclass总结
这张图能够清楚的描述 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对象,判断里面有没有要调用的方法,如果有就直接调用,没有就会通过class对象中的superclass找到父类,然后在父类中判断是否有该方法,如果还没有就接着往上找。
class调用类方法的轨迹:
isa找meta-class,方法不存在,就通过superclass找父类,最后基类mate-class也没有的话还会去基类对象找,这样就会导致调用类方法可能会去调用实例对象的方法
isa指针的一些问题
上面已经说到了instance对象的isa指针指向的是class对象,那就是说instance对象的isa指针内存地址是不是就是class对象的内存地址呢?
如果在以前的32位系统中确实如此,在64位系统中不是的,里面有一个点操作, ISA_MASK
其中arm64和x86架构的这个 ISA_MASK的偏移地址是不一样的,如下图:
class、meta-class对象的本质结构都是struct objc_class,如下图:
-----------------------------
本文参考借鉴MJ的教程视频,非常感谢.