七、Runtime介绍

描述

OC语言是一门动态语言,会将程序的一些决定工作从编译期推迟到运行期。 由于OC语言运行时的特性,所以其不只需要依赖编译器,还需要依赖运行时环境

OC语言在编译期都会被编译为C语言的Runtime代码,二进制执行过程中执行的都是C语言代码。而OC类本质上都是结构体,在编译时都会以结构体的形式被编译到二进制中。Runtime是一套由C、C++、汇编实现的API,所有的方法调用都叫做发送消息

根据Apple官方文档的描述,目前OC运行时分为两个版本,ModernLegacy。二者的区别在于Legacy实例变量发生改变后,需要重新编译其子类Modern实例变量发生改变后,不需要重新编译其子类

Runtime不只是一些C语言的API,其由ClassMeta ClassInstanceClass Instance组成,是一套完整的面向对象数据结构。所以研究Runtime整体的对象模型,比研究API是怎么实现的更有意义。

运行时编译时区别

  • 运行时 是代码跑起来,被装载到内存中的过程,如果此时出错,则程序会崩溃,是一个动态阶段

  • 编译时源代码翻译成机器能识别的代码的过程,主要是对语言进行最基本的检查报错,即词法分析语法分析等,是一个静态阶段

使用Runtime

Runtime是一个共享动态库,其目录位于/usr/include/objc,由一系列的C函数和结构体构成。和Runtime系统发生交互的方式有三种,一般都是用前两种:

使用OC源码
直接使用上层OC源码,底层会通过Runtime为其提供运行支持,上层不需要关心Runtime运行。
NSObject
在OC代码中绝大多数的类都是继承自NSObject的,NSProxy类例外。Runtime在NSObject中定义了一些基础操作,NSObject的子类也具备这些特性。
Runtime动态库
上层的OC源码都是通过Runtime实现的,我们一般不直接使用Runtime,直接和OC代码打交道就可以。

使用Runtime需要引入下面两个头文件,一些基础方法都定义在这两个文件中。

#import 
#import 

runtime使用有以下三种方式,其三种实现方法与编译层和底层的关系如图所示

  • 通过OC代码,例如 [person sayNB]

  • 通过NSObject方法,例如isKindOfClass

  • 通过Runtime API,例如class_getInstanceSizeclass_getInstanceMethod

图片.png

其中的compiler就是我们了解的编译器,即LLVM,例如OC的alloc 对应底层的objc_allocruntime system libarary 就是底层库

你可能感兴趣的:(七、Runtime介绍)