1. 语法上的“双重人格”
如果你观察 Objective-C 的代码,你会发现两种截然不同的风格共存:
- C 部分: 所有的基本类型(int, float)、控制流(if, for, while)和函数调用依然遵循 C 的静态编译逻辑。
- Smalltalk 部分: 所有方括号
[...]里的内容,都遵循 Smalltalk 的**消息传递(Message Passing)**逻辑。
2. “调用函数” vs “发送消息”
这是 Objective-C 与 C++ 或 Java 最本质的区别。
-
C 语言(静态绑定): 当你写
func()时,编译器在编译阶段就基本确定了要跳转到哪个内存地址去执行代码。 -
Objective-C(动态绑定): 当你写
[object method]时,它会被编译器转换成:
这并不是在“调用函数”,而是在发消息。对象收到消息后,会在运行时(Runtime)去寻找如何响应这个消息。如果对象直到运行那一刻才发现自己处理不了这个消息,它甚至可以转发给别的对象。这种灵活性完全继承自 Smalltalk。
3. 运行时(Runtime)的力量
Smalltalk 的核心思想是对象之间通过消息通信,而对象本身是高度自治的实体。为了在 C 语言中实现这一点,Objective-C 引入了一个极其强大的 Runtime 库。
| 特性 | C 风格 (静态) | Smalltalk 风格 (Obj-C 动态) |
|---|---|---|
| 决定执行逻辑的时间 | 编译时 | 运行时 |
| 不存在的方法 | 编译报错 | 运行时可以通过消息转发处理 |
| 方法查找 | 通过函数指针直接跳转 | 通过 Selector 在方法列表中查找 |
| 灵活性 | 低,结构固定 | 高,甚至可以在运行时给类增加方法 |
4. 为什么这么设计?
Objective-C 的发明者 Brad Cox 和 Tom Love 当时的想法很简单:
- C 语言足够快,能直接操作底层硬件,生态极广。
- Smalltalk 的开发效率极高,极其灵活,适合构建复杂的 GUI 系统。
于是他们创造了 Objective-C,让开发者既能享受 C 的性能,又能拥有类似 Smalltalk 那种“万物皆对象”和“高度动态化”的编程体验。这也是为什么早期的苹果开发文档里经常提到“发送消息”而不是“调用方法”。
有趣的事实: 即使是现在的 Swift,在处理很多底层交互时,依然离不开这一套来自 80 年代的 Smalltalk 消息机制。