本文由快学吧个人写作,以任何方式转载请表明原文出处。
一、材料预备
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 :
能够得到的信息是 :
- objc_class是一个承继于objc_object的结构体
- 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类型
-
万物皆目标,isa也是目标,也能够由Class接纳。
-
从isa的来历来看,源码中查找Class isa,找到isa的来历如下 :
- 找getIsa() :
- ISA()源码 :
- getDecodedClass源码 :
- getClass源码 :
从6中的图能够看到,回来的类型,会被强转为Class。也能够阐明为什么isa是Class类型的。
六、总结
- Class(类)的实质是objc_class
- objc_class是承继于objc_object的结构体
- 由上述两点能够得出,类的实质是objc_object。并且能够得出,万物皆目标。
- NSObject是OC仿写的objc_object,所以万物是NSObject与万物是objc_object是不抵触的。
- 类的结构体中有四个重要的成员,分别是isa(承继于objc_object),superclass(父类),cache(缓存),bits(数据)。