iOS 开发中 Objective-C 和 Swift 都用的是 Clang / LLVM 来编译的。LLVM是一个模块化和可重用的编译器和工具链技术的集合,Clang 是 LLVM 的子项目,是 C,C++ 和 Objective-C 编译器,目的是提供惊人的快速编译,比 GCC 快3倍,其中的 clang static analyzer 主要是进行语法分析,语义分析和生成中间代码,当然这个过程会对代码进行检查,出错的和需要警告的会标注出来。LLVM 核心库提供一个优化器,对流行的 CPU 做代码生成支持。lld 是 Clang / LLVM 的内置链接器,clang 必须调用链接器来产生可执行文件。
首先创建一个测试项目 ClangTest
然后创建一个Person类,在main.m文件里面alloc一个person对象
int main(int argc, const char * argv[]) {
@autoreleasepool {
// 我们来看看编译器在底层把这个创建的方法编译成成么样子了
Person *p = [[Person alloc] init];
// insert code here...
NSLog(@"Hello, World!");
}
return 0;
}
我做这一步的主要目的是想要看看,编译器在编译的时候把我的创建方法编程成么样子了。
我们打开终端,输入:
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;
}
看到了吗?我们创建 person 的 alloc , init 方法被编译成C语言了,这个C语言语法我们是不是很熟悉呢,没错,就是在objc/message 框架中见到的。这就是我们OC的方法本质(消息发送机制):objc_msgSend(),所有的OC方法底层都是这个消息发送实现的。这里面也会牵扯到runtime等好多有趣的东西,值的研究!!
网友评论