iOS 開發(fā)中 Objective-C 和 Swift 都用的是 Clang / LLVM 來編譯的。LLVM是一個模塊化和可重用的編譯器和工具鏈技術(shù)的集合,Clang 是 LLVM 的子項目,是 C,C++ 和 Objective-C 編譯器,目的是提供驚人的快速編譯,比 GCC 快3倍,其中的 clang static analyzer 主要是進(jìn)行語法分析,語義分析和生成中間代碼,當(dāng)然這個過程會對代碼進(jìn)行檢查,出錯的和需要警告的會標(biāo)注出來。LLVM 核心庫提供一個優(yōu)化器,對流行的 CPU 做代碼生成支持。lld 是 Clang / LLVM 的內(nèi)置鏈接器,clang 必須調(diào)用鏈接器來產(chǎn)生可執(zhí)行文件。
首先創(chuàng)建一個測試項目 ClangTest

然后創(chuàng)建一個Person類,在main.m文件里面alloc一個person對象
int main(int argc, const char * argv[]) {
????@autoreleasepool {
????????// 我們來看看編譯器在底層把這個創(chuàng)建的方法編譯成成么樣子了
????????Person *p = [[Person alloc] init];
????????// insert code here...
????????NSLog(@"Hello, World!");
????}
????return 0;
}
我做這一步的主要目的是想要看看,編譯器在編譯的時候把我的創(chuàng)建方法編程成么樣子了。
我們打開終端,輸入:
1.cd

把這個文件夾拖到終端里面,生成文件路徑,回車
輸入命令:
1.clang -rewrite-objc main.m
會在上面的文件夾下面生成一個 main.cpp,我這里只是以main.m文件為例,你也可以clang別的文件。

打開 main.cpp 文件,我們會看到幾萬行的代碼,很多哈,主要是Link了好多別的庫。拉到最下面,我們會看到
int main(int argc, const char * argv[]) {
????/* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool;
????????Person *p = ((Person *(*)(id, SEL))(void *)objc_msgSend)((id)((Person *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("Person"), sel_registerName("alloc")), sel_registerName("init"));
????????NSLog((NSString *)&__NSConstantStringImpl__var_folders_n9_3g_sywdx5pjdxrhx7f4yjvpc0000gn_T_main_dbc036_mi_0);
????}
????return 0;
}
看到了嗎?我們創(chuàng)建 person 的 alloc , init 方法被編譯成C語言了,這個C語言語法我們是不是很熟悉呢,沒錯,就是在objc/message 框架中見到的。這就是我們OC的方法本質(zhì)(消息發(fā)送機(jī)制):objc_msgSend(),所有的OC方法底層都是這個消息發(fā)送實現(xiàn)的。這里面也會牽扯到runtime等好多有趣的東西,值的研究??!