C语言,函数的调用在编译的时候会决定调用哪个函数。编译完成之后直接顺序执行,无任何二义性。而OC的函数调用成为消息发送。属于动态调用过程。在编译的时候并不能决定真正调用哪个函数(事实证明,在编 译阶段,OC可以调用任何函数,即使这个函数并未实现,只要申明过就不会报错。而C语言在编译阶段就会报错)。只有在真正运行的时候才会根据函数的名称找到对应的函数来调用。
我们如何找到RunTime源码?
Runtime源码下载链接:https://opensource.apple.com/release/macos-10141.html
打开链接,搜索objc 找到objc4最新版本下载即可。
本文编译环境
1、 Xcode版本:11.2.1
2、 MacOS版本:10.14.6
3、 Runtime版本:objc4-750.1
对于不同的Runtime版本及Xcode版本可能出现的错误也不一样,这篇文章主要是我在编译过程中遇到的错误信息以及解决方案,如果大家没有遇到对应的错误信息,直接跳过即可。
编译过程
打开objc.xcodeproj,编译运行,
1、编译报错:

解决方案:按图中步骤将Architectures选择Stand Architectures,点击objc target,也如下图修改。

2、编译报错,会缺少很多的文件
第一步:打开链接https://opensource.apple.com/release/macos-10141.html 下载:Libc、dyld、libauto、libclosure、libdispatch、xnu、libpthread、launchd、libplatform,全部下载下来解压到统一个目录下。
第二步:新建文件夹Common,之后我们会把所有的报错文件都放到该文件夹下。
第三步:Header search path,debug及release下添加$(SRCROOT)/Common,如下图。

第四步:逐步编译添加缺少的文件。
报错1:'reason.h' file not found
解决方案:打开终端,cd到第一步中统一的目录下,执行命令:find . -name 'reason.h' ,
终端打印./xnu-4570.71.2/bsd/sys/reason.h
在Common目录下新建sys文件夹,到文件夹下该文件夹下找到reason.h 添加到项目sys文件夹下,继续编译。
报错2:'dyld_priv.h' file not found,所在路径:./dyld-655.1.1/include/mach-o/dyld_priv.h,
添加后会在dyld_priv.h文件中报错Expected ',' 注释掉即可
*通上述步骤可找到文件添加到工程,为节省大家时间,相同的操作会列出缺少文件及对应找的目录
报错3:'lock_private.h' file not found
路径:./libplatform177.200.16/private/os/lock_private.h
报错4:'base_private.h' file not found
路径:./libplatform177.200.16/private/os/base_private.h
报错5:'tsd_private.h' file not found
路径:./libpthread-330.250.2/private/tsd_private.h
报错6:'cpu_capabilities.h' file not found
如果执行find . -name 'cpu_capabilities.h'会有三个文件,我们用./xnu-4570.71.2/osfmk/machine/cpu_capabilities.h 目录下文件
报错7:'tsd.h' file not found
会有两个文件,我们用:./xnu-4570.71.2/libsyscall/os/tsd.h
报错8:'spinlock_private.h' file not found
路径./libpthread-330.250.2/private/spinlock_private.h
报错9:'pthread_machdep.h' file not found
采用上述方案找不到该文件,我们需要采取新的方案,即在google搜索pthread_machdep打开第一条,自己在Common/System下新建文件,将内容拷贝进去。
拷贝后会报错:Typedef redefinition with different types ('int' vs 'volatile OSSpinLock' (aka 'volatile int')) 解决方案 将该文件中报错的地方注释掉
*注意如果注释不全这会报错-如果没有下图报错跳过次步骤

解决方案:一定将pthread_machdep.h文件中inline static int 这行代码注释掉
错误10:'CrashReporterClient.h' file not found
同报错9一样的方式解决,
错误11:'Block_private.h' file not found
路径./libclosure-73/Block_private.h对应目录./libdispatch-1008.250.7/src/BlocksRuntime/Block_private.h
错误12:'objc-shared-cache.h' file not found
路径:./dyld-655.1.1/include/objc-shared-cache.h
错误13:'_simple.h' file not found
路径./libplatform-177.200.16/private/_simple.h
错误14:'dyld_priv.h' file not found
路径./dyld-655.1.1/include/mach-o/dyld_priv.h
错误15:'isa.h' file not found
路径./objc4-750.1/runtime/isa.h
3、编译报错:
Use of undeclared identifier ‘CRGetCrashLogMessage’
解决方法:target -> Build Settings -> Preprocessor Macros 添加LIBC_NO_LIBCRASHREPORTERCLIENT,如下图。

4、编译报错:
Use of undeclared identifier 'DYLD_MACOSX_VERSION_10_13'
解决方案:在dyld_priv.h中添加下边代码:
#define DYLD_MACOSX_VERSION_10_11 0x000A0B00#define DYLD_MACOSX_VERSION_10_12 0x000A0C00#define DYLD_MACOSX_VERSION_10_13 0x000A0D00#define DYLD_MACOSX_VERSION_10_14 0x000A0E00
如下图:

5、继续编译报错:
can't open order file: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/AppleInternal/OrderFiles/libobjc.order
解决方法:如下图target -> objc -> Build Settings -> Order File
加入:$(SRCROOT)/libobjc.order,如下图:

6、继续编译报错:
library not found for -lCrashReporterClient
解决方法:删除lCrashReporterClient,如下图:

7、继续编译报错:
Undefined symbol: _objc_opt_class:
解决方法:

8、继续编译报错:

•解决方法:选择 target -> objc -> Build Phases -> Run Script(markgc)
•把脚本文本 macosx.internal 改成 macosx
9、继续编译报错:
error: no such public header file: '/tmp/objc.dst/usr/include/objc/ObjectiveC.apinotes'
解决方法:选择 target -> objc -> Build Settings
•Text-Based InstallAPI Verification Model 中添加搜索路径 Errors Only
将Supports Text-Based Install API 设为NO

编译通过
新建Target:runtimeTest 运行runtimeTest,runtimeTest下main.m文件里可以断点查看runtime源码。