iOS开发之 runtime(38) :Clang 入门

iOS开发之 runtime(38) :Clang 入门_第1张图片
logo

本系列博客是本人的源码阅读笔记,如果有 iOS 开发者在看 runtime 的,欢迎大家多多交流。为了方便讨论,本人新建了一个微信群(iOS技术讨论群),想要加入的,请添加本人微信:zhujinhui207407,【加我前请备注:ios 】,本人博客http://www.kyson.cn 也在不停的更新中,欢迎一起讨论

本文完整版详见笔者小专栏:https://xiaozhuanlan.com/runtime

前言

可能大部分读者看到这一篇的时候有点疑惑,说好的 runtime 呢,怎么变成看似毫无相关性的 Clang 了。不急,且听笔者慢慢道来。大家可能知道我们的 Objective-C 的代码是通过转换成 C 语言来实现的。但究竟是怎么转换的可能大家还不太清楚,这个时候如果不引进 Clang 的知识点的话,后面的 Objective-C 转换成 C 语言的部分就说不清楚了。接下来的文章笔者会带大家稍微了解一下 Clang 的知识点,不需要你对 Clang 多精通,只需要够我们将 Objective-C 转换成 runtime 的部分说清楚即可。

Clang 大家应该不陌生了,这里援引一段维基百科介绍一下吧。

Clang(发音为/ˈklæŋ/ 类似英文单字clang) 是一个 C、C++、Objective-C 和 Objective-C++ 程式语言的编译器前端。它采用了 LLVM 作为其后端,而且由LLVM2.6开发,一起释出新版本。它的目標是提供一個GNU编译器套裝(GCC)的替代品,支援了 GNU 编译器大多數的编译设定以及非官方语言的扩充功能。作者是克里斯·拉特納(Chris Lattner),在苹果公司的赞助支持下進行开发,而原始码授权是使用类 BSD 的伊利诺伊大学厄巴纳-香槟分校开源码许可。

分析

Xcode 中敲入如下代码:

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSObject *obj = [[NSObject alloc] init];
        NSLog(@"%@",obj);
    }
    return 0;
}

经过前面系列文章的介绍,大家知道我们在调用 NSObject 类的方法时会调用 runtime 中对应的方法。
比如 alloc 方法 和 init 方法会跳转到 runtime 的源码,如图:

iOS开发之 runtime(38) :Clang 入门_第2张图片
打断点
iOS开发之 runtime(38) :Clang 入门_第3张图片
进入 runtime 中的方法

但我们还有其他的疑点:

  • @autoreleasepool 被转换成了什么?
  • Objective-C 和 C 究竟是怎么转化的?或者是否真的存在过转化?

要回答这个问题,难度也不大,稍加搜索,大家会搜到 Clang 的一个指令:

clang -rewrite-objc

该指令能将 Objective-C 语言重写为 C 语言。于是一大部分读者会认为, Objective-C 在编译过程中会先将 Objective-C 转化为 C 语言,然后再进行编译。那么结果是否真的是这样呢?

要回答这个问题,笔者找到了 stack over flow 上的一个提问

Recently, I have one problem. The clang can translate Objective-C to c++ use -rewrite-objc. So I think, the first step. clang compile Objective-C to C++. And then compile only can use c++ compiler. Is it do like this? clang first translate Objective-C to C++ with runTime, and then compile to the machine code?

回答如下:

-rewrite-objc exists to translate ObjC to C++ so it can be compiled in the Visual Studio. It is still Objective-C semantics and you still need the objective-c runtime. It is not magically converting Objective-C to the C++ OO architecture.
This is much more like when Objective-C was implemented as a pre-compiler extension.
It all relies on the fact that Objective-C classes are just C structures with fancy behavior and objective-c method calls all can be translated to calls to objc_msgSend().

因此,其实 -rewrite-objc 并不是 Objective-C 的真正编译时的实现。那么编译时期是怎么实现的呢,笔者将在后面的文章中给与讲解。

你可能感兴趣的:(iOS开发之 runtime(38) :Clang 入门)