本文由快学吧个人写作,以任何方式转载请表明原文出处。

一、材料预备

objc4-818.2 : github.com/LGCooci/KCO…

对应mac的版别是11.1。可根据自己的系统版别选择能够进行调试的源码

二、探索思路

1、创立一个目标,获取这个目标的类

2、利用clang,将源码编译。

3、查看编译后的类。

4、找到类的数据结构

5、在源码内进行一层一层的分析。

三、创立项目

创立一个自界说的类,承继于NSObject。在818.2的main.m中创立这个类的实例目标,然后用Class获取这个实例目标的类信息。用Class的原因是oc中所有的类都能够用Class来接纳。所以具有普遍性。

六、类的本质和结构

从terminal终端进入项目地点的文件夹,进入到main.m地点的文件夹下,然后用clang进行编译,clang指令 : clang -rewrite-objc main.m -o main.cpp

在生成的main.cpp文件中查找自界说的类,例如我自界说的JDPerson,会发现JDPerson是一个objc_object结构体。

六、类的本质和结构

再看Class是什么结构。查找Class,硬找太困难,所以找规律,看JDPerson,发现一个类被编译后,能够发现它的实质的当地,都有一种格式 : “类 + ;”。

所以查找Class;,一共49个,很好找,Class的实质也是结构体,是objc_class结构体,如下图 :

六、类的本质和结构

所以普通的承继类的实质是objc_object,而Class编译后的实质是objc_class。这是在这儿得到的一个信息。

四、源码探索类的实质

源码中查找objc_class :

六、类的本质和结构

能够得到的信息是 :

  1. objc_class是一个承继于objc_object的结构体
  2. objc_class有四个成员,可是成员ISA被注释。

为什么ISA成员被注释?可是还要放在代码里面,其实是相当于占位,告诉看到这儿的人,这儿是应该有一个ISA的。已然子类没有,那么ISA就应该是承继于父类的,所以查找objc_object的源码,如下 :

六、类的本质和结构

找到了ISA。从上述源码,能够得到的信息是,所谓的万物皆目标,便是万物皆objc_object。全部类的源头,便是objc_object。

而我们常说的万物皆NSObject,和这儿是否有抵触?查看NSObject的界说,在源码中找到NSObject.h文件 :

六、类的本质和结构

能够看到NSObject的界说和objc_object的结构是彻底一样的,也便是说,NSObject是objc_object的一种仿写。objc_object是编译后的结构,NSObject是编译前的界说,所以万物皆NSObject也是没有问题的,并不抵触。

五、为什么isa是Class类型

  1. 万物皆目标,isa也是目标,也能够由Class接纳。

  2. 从isa的来历来看,源码中查找Class isa,找到isa的来历如下 :

六、类的本质和结构

  1. 找getIsa() :

六、类的本质和结构

  1. ISA()源码 :

六、类的本质和结构

  1. getDecodedClass源码 :

六、类的本质和结构

  1. getClass源码 :

六、类的本质和结构

从6中的图能够看到,回来的类型,会被强转为Class。也能够阐明为什么isa是Class类型的。

六、总结

  1. Class(类)的实质是objc_class
  2. objc_class是承继于objc_object的结构体
  3. 由上述两点能够得出,类的实质是objc_object。并且能够得出,万物皆目标。
  4. NSObject是OC仿写的objc_object,所以万物是NSObject与万物是objc_object是不抵触的。
  5. 类的结构体中有四个重要的成员,分别是isa(承继于objc_object),superclass(父类),cache(缓存),bits(数据)。