Objective-C 语言是一门动态语言,它将很多静态语言在编译和链接时期做的事放到了运行时来处理。
Objective-C 是基于 C 语言加入了面向对象特性和消息转发机制的动态语言,这意味着它不仅需要一个编译器,还需要 Runtime 系统来动态创建类和对象,执行编译的代码,进行消息发送和转发。
Objective-CRuntime 其实是一个 Runtime 库,它基本上是用 C 和汇编写的,这个库使得 C 语言有了面向对象的能力。

下面通过分析 Apple开源的Runtime代码 来深入理解 Objective-CRuntime 机制。

初学 Objective-C 时,

1
[object doSomething]

当成一个简单的方法调用,而无视了消息发送这句话的深刻含义,后来对 Runtime 的理解慢慢增加了,逐渐明白了消息发送的含义。

借助 clang 编译器,当执行 [object doSomething] 会被编译器转化为:

1
2
3
clang -rewrite-objc xxx.m
SEL doSomethingSel = @selector(doSomething);
objc_msgSend(object, doSomethingSel);

打开 objc_msgSend,需要设置一下类型检查参数;
image.png
无参数,则为:

1
objc_msgSend(receiver, selector)

如果消息含有参数,则为:

1
objc_msgSend(receiver, selector, arg1, arg2, ...)

如果消息的接收者能够找到对应的 selector,那么就相当于直接执行了接收者这个对象的特定方法;否则,消息要么被转发,或是临时向接收者动态添加这个 selector 对应的实现内容,要么就干脆玩完崩溃掉。

现在可以看出 [object doSomething] 不是一个简简单单的方法调用,因为这只是在编译阶段确定了要向接收者发送 doSomething 这条消息,而 receive 将要如何响应这条消息,那就要看运行时发生的情况来决定了。