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

一、如何了解目标的实质

oc的底层编译都会变成c和c++的代码,所以要了解目标的实质,就要看oc的代码被编译成了什么样的c或许c++的数据类型和结构。

二、创立一个新的mac项目

为什么挑选mac的项目?由于mac的项目不会引进太多的UIKit框架的代码,在检查编译完结的代码的时分,更加的简略,又不会影响主要的探究目的。

创立如下的一个项目。最简略的界说一个类承继于NSObject。

五、对象的本质和签名

三、运用Terminal终端,利用clang指令获得编译后的文件

clang指令 :


//mac项目编译成c++文件
1clang -rewrite-objc main.m -o main.cpp //将oc的.m文件编译成c++并输出.cpp文件。
//提示存在UIKit引用库的问题,用下面这个
2clang -x objective-c -rewrite-objc -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk ViewController.m
//xcrun xcode的指令
3xcrun -sdk iphonesimulator clang -rewrite-objc ViewController.m
4xcrun -sdk iphones clang -rewrite-objc ViewController.m

上面是需要用到的一些clang的指令,由于我创立的是mac的项目,只有一个main.m,没有引进UIKit库,所以直接用第一条指令。

首先要进入main.m地点的项目文件夹,然后在运用第一个指令,否则找不到main.m的文件。

生成了main.cpp文件。打开main.cpp文件查找咱们界说的JDMan。

五、对象的本质和签名

能够看出,目标的实质是一个结构体。尽管我没有给JDMan界说成员变量或许特点,可是结构体中依然存在一个NSObject_IMPL,这个便是isa,是JDMan的父类NSobject自带的特点。如下图 :

五、对象的本质和签名

所以,目标在编译后,实质上是结构体,并且会承继父类的特点。

四、特点和成员变量和实例变量之间的不同

曾经常常会被问到特点和成员变量(实例变量)之间有什么不同,只知道不同点是 : 特点 = 成员变量 + getter + setter。

那么从编译后的源码中就能够找到证据。

添加特点和成员变量 :

五、对象的本质和签名

clang进行编译,步骤如同上面。clang -rewrite-objc main.m -o main2.cpp生成main2.cpp文件。找到main函数上面,直接搜索int main(

编译后的源码如下 :

五、对象的本质和签名

如图中所写,这便是为什么说成员变量和实例变量与特点之间有不同。别的实例变量也是一种特殊的成员变量,一般对非基础类的、能够实例化的变量,会被叫做实例变量,例如 JDCar,而基础类的NSString尽管也是一种实例,可是这一类一般会被称作成员变量。

五、签名

特点是带有set和get办法的,那么它们的实现,在编译后会如下图所示(仍是main2.cpp文件中) :

五、对象的本质和签名

这儿便是一个sel和imp的关系,函数名便是一个函数指针。里面的@16@0:8,这种东西叫函数签名。

详细的信息官方有官网文档,所以只解释一下这个签名的意义。

以@16@0:8举例 :

@是返回值的类型是id,16是指办法占用的总共的内存量,第二个@表明第一个参数类型是id,0是指第一个参数是从0位开端,: 表明第二个参数,8表明第二个参数从第8位开端。