开始学习 iOS 后,第一次看到 Objective-C 代码时,很容易感到困惑。
因为代码里到处都是方括号 [ ]。看起来像函数调用,但外观和其他语言差别太大了。
难免会留下“为什么要设计成这样?”的疑问。
先说结论,Objective-C 的方括号不是在“调用”函数,而是向对象“发送消息”的语法。只要理解这个概念,原本陌生的方括号就会突然变得容易读懂。
今天就从它的根源开始,轻松讲讲方括号为什么长成这样。😊
先从核心摘要开始
首先,整理一下这篇文章可以学到的内容。
- Objective-C 的方括号表示“向对象发送消息”
- 这种语法继承自 Smalltalk 语言
- 只要了解
[객체 메서드]这一结构,就能读懂大多数代码 - 在内部会转换为名为
objc_msgSend的函数后执行
理解这四点,今天的目标就全部达成了。
Objective-C 的消息发送语法到底是什么?
在其他语言中调用方法时,通常会这样写。
object.method()
但在 Objective-C 中会这样写。
// dog 向对象发送 bark 消息
[dog bark];
// count 把值作为参数一起发送
[dog barkTimes:3];
虽然外观看起来陌生,但结构很简单。
[받는객체 보낼메시지]
打开方括号,左边放接收消息的对象,右边写要发送的消息。
所以,[dog bark]的意思就是“dog,请 bark”。
我把它理解成不是“函数调用”,而是“和对象说话”,这样就容易多了。
有多个参数时,结构会像这样扩展。
// 消息名称会 setName:age: 分成两部分
[person setName:@"哲洙" age:20];
可以把它理解为每个冒号(:)后面都会跟一个值。
方括号为什么长这样?
Objective-C 的方括号,是将 Smalltalk 的“消息发送”理念融入 C 语言后留下的痕迹。
故事要追溯到 20 世纪 80 年代初。
Objective-C 由 Brad Cox 和 Tom Love 两人创建。
他们想继续使用当时流行的 C 语言,同时加入面向对象的概念。
这种面向对象思想的典范正是 Smalltalk。
Smalltalk 的核心理念是:“一切都是对象,对象之间通过消息进行通信”。
问题在于,必须在不破坏 C 语法的前提下加入消息这一概念。
因此,他们选用了 C 语法中几乎不用的方括号,把其中定义为发送消息的空间。
这样即使和现有 C 代码混用,也能避免冲突并加以区分。
后来,NeXT 采用了这门语言;Apple 在 1996 年收购 NeXT 后,它成为 Mac 和 iPhone 开发的基础。
我们熟悉的 Cocoa 框架也由此诞生。
一个陌生的方括号背后,竟然承载着如此漫长的历史。
它和点号(.)语法有什么不同?
如今的 Objective-C 代码中也经常能看到点号(.)语法。
比如 dog.name。
因此很容易混淆,我把两者的关系整理成了表格。
| 分类 | 方括号语法 | 点号(.)语法 |
|---|---|---|
| 形式 | [dog name] |
dog.name |
| 含义 | 消息发送 | 属性访问 |
| 出现时期 | 从早期开始 | Objective-C 2.0(2007 年)之后 |
| 内部行为 | 执行方法 | 实际上转换为方法 |
有趣的是,点号语法最终也会在内部转换为方括号消息。
也就是说,dog.name执行时做的事情和[dog name]相同。
点号语法只是为了方便阅读而加上的外衣。
所以我建议初学者先理解,本质其实是方括号。
方括号内部到底发生了什么?
让我们再深入一点。
写下 [dog bark] 时,编译器会把它转换为对 objc_msgSend 函数的调用。
// 我们写的代码
[dog bark];
// 在内部大致会转换成这样
objc_msgSend(dog, @selector(bark));
第一个位置放接收消息的对象,第二个位置放要执行的方法名称标签(selector)。
这种方式很灵活,因为可以在运行时决定要执行哪个方法。
因此,Objective-C 很擅长在运行过程中修改或添加方法等动态功能。
方括号的外表之下,原来隐藏着这样灵活的结构。
通过问答做个总结
问:一定要记住方括号吗?
与其死记硬背,只要掌握 [받는객체 보낼메시지] 这一结构,就能自然读懂。
问:我现在使用 Swift,还需要了解吗?
许多旧库和示例代码至今仍使用 Objective-C 编写,所以能够读懂会很有帮助。
问:如果方括号里面还有方括号呢?
这是外层再次接收内层结果的结构。从内向外阅读就能理解。
方括号看起来只是奇怪的规则,但换个角度,把它理解成“和对象说话的语法”,就会亲切得多。
越是陌生的语法,了解它的根源后反而越容易长久记住。
希望这篇文章能成为你进一步了解 Objective-C 的契机。为你加油!🙌

