本系列博客是本人的源碼閱讀筆記,若是有iOS開發者在看runtime的,歡迎你們多多交流。爲了方便討論,本人新建了一個微信羣(iOS技術討論羣),想要加入的,請添加本人微信:zhujinhui207407,【加我前請備註:ios 】,本人博客http://www.kyson.cn 也在不停的更新中,歡迎一塊兒討論 ios
相信接觸過iOS的同窗對runtime或多或少都有耳聞。 建立一個對象:git
[[NSObject alloc] init];
複製代碼
點擊進入其定義: github
能夠發現其進入了文件NSObject.h
中 面試
右擊該文件,選擇:show in Finder
能夠看到runtime
暴露給咱們的文件: bash
雖然暴露給咱們的很少,但其實已經能提供給咱們不少功能,剛剛咱們的對象建立就是一個典型的功能。 衆所周知,NSObject
對象是Objective-C語言中幾乎全部對象的根類。換言之,任何一個對象的建立都是經過runtime實現的,僅此一點,runtime的重要性可見一斑,如今的iOS面試也愈來愈經過對runtime的面試來區分iOS開發人員的水平高低。微信
筆者研究runtime源碼有一段時間了,隨着研究的深刻,對runtime的實現也愈來愈感興趣,所以想寫一套系列教程來和你們討論runtime的底層實現。app
蘋果開源了runtime的實現,在網站 opensource.apple.com/source/objc… 中能夠找到各個版本的runtime源碼。 但提供的是一個個文件,不方便打包下載,網站 opensource.apple.com/tarballs/ob…中提供了壓縮包的下載。函數
下載下來的runtime源碼是運行不了的,缺乏一些依賴文件,找起來也比較繁瑣。這裏筆者fork了一份,供你們參考(該項目編譯過程你們能夠參考這篇文章:objc - 編譯Runtime源碼objc4-680):網站
如圖,打開工程後選擇工程debug-objc,點擊run便可。因爲debug-objc依賴於objc(即runtime的源代碼編譯的庫),所以咱們在main函數中全部Objective-C的代碼會調用咱們編譯的runtime,從而方便咱們調試。
runtime源碼目錄結構以下:
include
文件夾是咱們引入的項目須要的依賴文件
Public Headers
文件夾是對外暴露的,點開後咱們不難發現,和文章開頭給出的文件列表如出一轍:
Private Headers
從字面意思瞭解,是私有的一些方法
Project Headers
runtime項目中會用到的頭文件
Obsolete Headers
一些孤立
的文件,大部分可刪,只有hashtable2.h
的文件會被其餘文件使用到。
Obsolete Source
無實質用處,可全刪
Source
目錄,是runtime的實現文件集合,後面的文章主要是研究這個目錄。
在咱們的main.m中,輸入如下代碼:
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSObject *obj = [[NSObject alloc] init];
}
return 0;
}
複製代碼
打斷點後,咱們會發現NSObject *obj = [[NSObject alloc] init];方法最終會調用到runtime中的NSObject.mm中。也就是說,對象的建立都是在NSObject.mm中完成的。 具體實現流程,會在後面的文章中逐步揭曉。
有人反饋項目編譯不能經過,報以下錯誤:
dyld: Symbol not found: _objc_debug_taggedpointer_obfuscator
Referenced from: /usr/lib/system/libxpc.dylib
Expected in: ~/Library/Developer/Xcode/DerivedData/objc-ehlaekvxhzkjtdcmtvyuyxuygmfk/Build/Products/Debug/libobjc.A.dylib
in /usr/lib/system/libxpc.dylib
複製代碼
緣由是由於系統版本過高,與runtime版本不兼容致使的。目前最新的runtime能夠在這裏下載: objc4-750適用於系統macOS Mojave。
dyld: Symbol not found: _objc_debug_taggedpointer_obfuscator