Runtime,是一套底層的 C 語言 API罪塔,是 iOS 系統(tǒng)的核心之一投蝉。開發(fā)者在編碼過程中,可以給任意一個對象發(fā)送消息征堪,在編譯階段只是確定了要向接收者發(fā)送這條消息瘩缆,而接受者將要如何響應(yīng)和處理這條消息,那就要看運行時來決定了佃蚜。
C語言中庸娱,在編譯期着绊,函數(shù)的調(diào)用就會決定調(diào)用哪個函數(shù)。
而OC的函數(shù)熟尉,屬于動態(tài)調(diào)用過程归露,在編譯期并不能決定真正調(diào)用哪個函數(shù),只有在真正運行時才會根據(jù)函數(shù)的名稱找到對應(yīng)的函數(shù)來調(diào)用斤儿。
Objective-C 是一個動態(tài)語言靶擦,這意味著它不僅需要一個編譯器,也需要一個運行時系統(tǒng)來動態(tài)得創(chuàng)建類和對象雇毫、進行消息傳遞和轉(zhuǎn)發(fā)玄捕。
調(diào)試環(huán)境
- Xcode版本: 10.1
- Runtime源碼版本: objc4-750.1
代碼地址
版本750.1官方源碼地址: objc4-750.1.tar.gz
官方歷史源碼地址列表: runtime歷史源碼版本列表
讓Runtime源碼可以編輯步驟還是比較多這里放置一份我已經(jīng)編譯通過的代碼 點這里
開始編譯源代碼
下載完代碼的目錄如圖
最終結(jié)果就是編譯Products目錄下的libobjc.A.dylib。開始編譯按照提示依次解決直到成功編譯棚放。
1. i386架構(gòu)廢棄
- 錯誤提示信息
The i386 architecture is deprecated. You should update your ARCHS build setting to remove the i386 architecture. (in target 'objc-trampolines')
The i386 architecture is deprecated. You should update your ARCHS build setting to remove the i386 architecture. (in target 'objc')
提示的是在target 'objc-trampolines' 和 'objc'中i386已經(jīng)廢棄了枚粘。
- 解決方案
分別從tatget中移除i386架構(gòu),進入TARGETS->objc->Build Settings->Architectures 將"Debug"修改成Standard Architectures
2. 缺少文件
缺少的文件點擊 這里下載飘蚯。
- 錯誤提示信息
會出現(xiàn)以下缺失文件的提示下面羅列出來
'sys/reason.h' file not found
'mach-o/dyld_priv.h' file not found
'os/lock_private.h' file not found
'os/base_private.h' file not found
'pthread/tsd_private.h' file not found
'System/machine/cpu_capabilities.h' file not found
'os/tsd.h' file not found
'pthread/spinlock_private.h' file not found
'System/pthread_machdep.h' file not found
'Block_private.h' file not found
'objc-shared-cache.h' file not found
'_simple.h' file not found
- 解決方案
在工程目錄下創(chuàng)建一個新的文件夾名字可以隨便起我命名為Common將剛才下載的文件都放在里面馍迄,
接下來把文件添加到Header Search Paths中,進入TARGETS->objc->Build Settings 直接搜索Header Search Paths局骤,把$(SRCROOT)/Common添加進去攀圈。
下面根據(jù)信息的提示在Common目錄下新建文件夾sys,將剛才下載的reason.h文件拖動到sys文件夾里這樣我們就解決了sys/reason.h' file not found這個錯誤峦甩,其他的提示都是類似解決方法赘来。
Common內(nèi)部結(jié)構(gòu)
3. pthread_machdep.h文件的錯誤
- 提示信息
Static declaration of '_pthread_has_direct_tsd' follows non-static declaration
Static declaration of '_pthread_getspecific_direct' follows non-static declaration
Typedef redefinition with different types ('int' vs 'volatile OSSpinLock' (aka 'volatile int'))
-
解決方案
注釋掉pthread_machdep.h中錯誤提示代碼,從提示的位置注釋到最后凯傲。
4. objc-runtime-new.mm文件的錯誤
- 錯誤提示信息
Use of undeclared identifier 'DYLD_MACOSX_VERSION_10_11'
Use of undeclared identifier 'DYLD_MACOSX_VERSION_10_14'
- 解決方案
在我們剛剛添加的Common文件夾中的dyld_priv.h頭部添加相關(guān)的宏定義犬辰。
#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. 缺少CrashReporterClient.h
CrashReporterClient.h文件僅僅放在Common目錄下還不行還要做一些其他處理。
- 錯誤提示信息
Use of undeclared identifier 'CRGetCrashLogMessage'
Use of undeclared identifier 'CRSetCrashLogMessage'
- 解決方案
進入TARGETS->objc->Build Settings 直接搜索preprocessor冰单,在Preprocessor Macros中添加 LIBC_NO_LIBCRASHREPORTERCLIENT幌缝。
6. can't open order file
- 錯誤提示信息
ld: can't open order file: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/AppleInternal/OrderFiles/libobjc.order
clang: error: linker command failed with exit code 1 (use -v to see invocation)
- 解決方案
進入TARGETS->objc->Build Settings->Linking->Order File 修改為$(SRCROOT)/libobjc.order。
7. not found for -lCrashReporterClient
- 錯誤提示信息
ld: library not found for -lCrashReporterClient
clang: error: linker command failed with exit code 1 (use -v to see invocation)
- 解決方案
進入TARGETS->objc->Build Settings->Linking->Other Linker Flags中刪除lCrashReporterClient诫欠,DEBUG和RELEASE都刪除涵卵。
8. macosx.internal不能被定位到
- 錯誤提示信息
SDK "macosx.internal" cannot be located.
unable to find utility "clang++", not a developer tool or in PATH
- 解決方案
進入TARGETS->objc->Build Phases->Run Script,將腳本里面的macosx.internal->macosx荒叼。
9. public header
- 錯誤提示信息
no such public header file: '/tmp/objc.dst/usr/include/objc/ObjectiveC.apinotes'
- 解決方案
第一步: 進入TARGETS->objc->Build Settinngs->Text-Based API->Other Text-Based InstallAPI Flags轿偎,將里面的內(nèi)容設(shè)置為空。
第二步: 將Text-Based InstallAPI Verification Mode改為Errors Only甩挫,如圖
編譯成功
到此為止這份源代碼就可以通過編譯了贴硫,現(xiàn)在看一下工程目錄,可以看到Products下面的庫變成了黑色伊者。
添加新的TARGETS進行調(diào)試
PS: 后續(xù)會有一系列關(guān)于runtime的總結(jié)英遭,如有理解不妥,歡迎交流