返回

iOS14 类加载原理剖析

IOS

引言

类加载是程序执行的重要组成部分。它使应用程序能够动态加载和使用类和库,从而实现模块化和可扩展性。在 iOS14 中,类加载过程由一系列函数组成,这些函数负责加载、解析和链接类和库。本文将详细介绍 iOS14 中类加载的原理,从objc_init函数开始,我们将逐步分析类加载过程中的各个步骤。

objc_init

objc_init函数是类加载过程的入口点。它由应用程序的main函数调用,用于初始化Objective-C运行时环境。objc_init函数首先调用environ_init函数,然后调用tls_init函数。

environ_init

environ_init函数用于读取影响运行时的环境变量。如果需要,还可以打印环境变量帮助信息。例如,如果将环境变量OBJC_HELP设置为1,则environ_init函数将打印有关Objective-C运行时的帮助信息。

tls_init

tls_init函数用于初始化线程key绑定。线程key绑定是一种将数据与线程关联的技术。Objective-C运行时使用线程key绑定来存储每个线程的局部变量。例如,每个线程都有一个名为OBJC_THREAD_KEY的线程key,用于存储该线程的当前类。

dyld

dyld是动态链接器,负责加载和链接动态库。当应用程序启动时,dyld会加载应用程序的主可执行文件,然后加载应用程序所需的动态库。dyld使用一种称为延迟绑定技术来链接动态库。延迟绑定是指在应用程序启动时,dyld不会立即解析和链接动态库中的符号。而是等到应用程序需要使用这些符号时,dyld才会解析和链接它们。

dlopen

dlopen函数用于加载动态库。当应用程序需要使用动态库中的符号时,它会调用dlopen函数来加载该动态库。dlopen函数会将动态库加载到内存中,并返回一个句柄。应用程序可以使用这个句柄来访问动态库中的符号。

dlsym

dlsym函数用于解析动态库中的符号。当应用程序需要使用动态库中的符号时,它会调用dlsym函数来解析该符号。dlsym函数会返回符号的地址。应用程序可以使用这个地址来调用动态库中的函数。

dyld_stub_binder

dyld_stub_binder函数用于将延迟绑定的符号绑定到实际的地址。当应用程序调用延迟绑定的符号时,dyld_stub_binder函数会将该符号绑定到实际的地址。这样,应用程序就可以调用该符号了。

objc_msgSend

objc_msgSend函数是Objective-C中用于发送消息的对象。当应用程序调用Objective-C中的方法时,它会调用objc_msgSend函数来发送消息。objc_msgSend函数会找到接收消息的对象,然后调用该对象的方法。

objc_sendSuper

objc_sendSuper函数是Objective-C中用于发送消息给超类的对象。当应用程序调用Objective-C中的super方法时,它会调用objc_sendSuper函数来发送消息。objc_sendSuper函数会找到接收消息的对象的超类,然后调用该超类的方法。

结论

本文详细介绍了 iOS14 中类加载的原理。从objc_init函数开始,我们逐步分析了类加载过程中的各个步骤,包括environ_init、tls_init、dyld、dlopen、dlsym、dyld_stub_binder、objc_msgSend和objc_sendSuper。通过这些步骤,我们深入了解了类加载机制是如何工作的,以及它是如何使应用程序能够动态加载和使用类和库的。