asunquan.com

不忘初心 不止于行

职场新人 iOS菜鸟 就职于搜狐畅游 从事iOS/tvOS的SDK开发 对于游戏市场有点点了解 平日和一只小Corgi同吃同睡


[转]面试题: 为什么 Objective-C 的方法调用要用方括号?

题目

**为什么 Objective-C 的方法调用要用方括号 [obj foo] , 而不是别的语言常用的点 obj.foo ? **

分析及答案

首先要说的是, Objective-C 的历史相当久远, 如果你查 wiki 的话, 你会发现 Objective-C 和 C++ 这两种语言的发行年份都是1983年. 在设计之初, 二者都是作为 C 语言的面向对象的接班人, 希望成为事实上的标准. 最后结果大家都知道了, C++ 最终胜利了, 而 Objective-C 在之后的几十年中, 基本上变成了苹果自己家玩的玩具. 不过最终, 由于 iPhone 的出现, Objective-C 迎来了第二春, 在 TOBIE 语言排行榜上, 从 20 名开外一路上升, 排名曾经超越过 C++, 达到了第三名, 但是随着 Swift 的出现, 导致Objective-C 的排名则一路下滑.

Objective-C 在设计之初参考了不少 Smalltalk 的设计, 而消息发送则是向 Smalltalk 学来的. Objective-C 当时采用了方括号的形式来表示发送消息, 为什么没有选择用点呢? 我个人觉得是, 当时市面上并没有别的面向对象语言的设计参考, 而 Objective-C 发明了方括号的形式来给对象发消息, 而 C++ 则发明了用点的方式来发消息. 有人可能会争论说 C++ 的点并不是真正的发消息, 但是其实二者都是表示调用对象所属的成员函数.

另外, 有读者评论说使用方括号的形式是为了向下兼容 C 语言, 我并不觉得中括号是唯一选择, C++ 不也兼容了 C 语言么? Swift 不也可以调用 C 函数么?

最终, 其实是 C++ 的发明显得更舒服一些, 所以后来的各种语言都借鉴了 C++ 的这种设计, 也包括 Objective-C 在内, Objective-C 2.0 版本中, 引入了 dot syntax, 即:

  • a = obj.foo 等价于 a = [obj foo]
  • obj.foo = 1 则等价于 [obj setFoo:1]

Objective-C 其实在设计之中确实是比较特立独行的, 除了方括号的函数调用方式外, 还包括比较长的, 可读性很强的函数命名风格.

我个人并不讨厌 Objective-C 的这种设计, 但是从 Swift 语言的设计来看, 苹果也开始放弃一些 Objective-C 的特点了, 比如就去掉了方括号这种函数调用方式.

所以, 回到我们的问题, 我个人认为, 答案就是: Objective-C 在 1983 年设计的时候, 并没有什么有效的效仿对象, 于是就发明了一种有特点的函数调用方式, 现在看起来, 这种方式比点操作符还是略逊一筹.

大多数语言一旦被设计好, 就很难被再次修改, 应该说 Objective-C 发明在 30 年前, 还是非常优秀的, 它的面向对象化设计得非常纯粹, 比 C++ 要全面得多, 也比 C++ 要简单得多.

我很高兴能够使用它来开发 iOS 程序, 当然, 我更期待未来 Swift 给我带来的惊喜.

最近的文章

[转]面试题: 实现一个嵌套数组的迭代器

题目给你一个嵌套的 NSArray 数据, 实现一个迭代器类, 该类提供一个 next() 方法, 可以依次的取出这个 NSArray 中的数据.比如 NSArray 如果是 [1, [4, 3], 6, [5, [1, 0]]], 则最终应该输出: 1, 4, 3, 6, 5, 1, 0.**另外, 实现一个 allObjects 方法, 可以一次性取出所有元素. **分析及答案本题的代码稍长, 完整的代码我放在 gist 上了: https://gist.github.com/tang...…

iOS开发面试题继续阅读
更早的文章

[转]面试题: weak的内部实现

题目**weak 变量在引用计数为0时, 会被自动设置成 nil, 这个特性是如何实现的? **分析及答案在 Friday QA 上, 有一期专门介绍 weak 的实现原理. Zeroing Weak References in Objective-C[Objective-C高级编程]一书中也介绍了相关的内容.简单来说, 系统有一个全局的 CFMutableDictionary 实例, 来保存每个对象的 weak 指针列表, 因为每个对象可能有多个 weak 指针, 所以这个实例的值是 C...…

iOS开发面试题继续阅读