消息的点符号不仅仅是 Objective-C 代码的味道。我告诉你,它是恶魔😈!
更新:我最近改变了主意!请参阅我的文章《我接受的点符号...》
- 本文是Objective-C 中的代码气味系列文章中的一篇。*
......是的,这是夸张的说法。在有点符号的项目中,我确实能与点符号共存。但我不会自己写。以下是我避免在代码中使用点符号的三个原因:
1、点符号混淆了对象和结构体
告诉我,下面的代码是做什么用的?
foo.bar = 10;
在 C 语言中,这段代码的作用显而易见:foo
要么是一个结构体,要么是一个联合体。它在给 foo
的 bar
字段赋值 10
。
在引擎盖下,编译器会编写代码来计算 foo
的内存偏移量,然后将值 10
写入计算出的地址处的存储空间。速度非常快,而且非常轻便。
Objective-C 是 C 语言的严格超集,因此所有这些也适用于 Objective-C 代码。或者不适用。......你说不清楚,对吧?
2、点符号掩盖了消息传递
因为点符号是消息传递的语法糖,所以你可以写出这样的代码:
NSMutableArray *a = NSMutableArray.array;
当然,这已经超出了恶魔的范畴。但为什么呢?"因为数组不是属性,而是方法"。哦,所以用括号还是用点取决于这个东西是不是属性?但不管用哪种方式,都是传递消息!为什么还要添加第二种消息传递语法呢?
在 Objective-C 中加入点符号,让人联想到苹果公司的某个人说:
Java is such a popular language. Our square brackets freak out Java programmers. Let’s replace brackets with dots; it’ll look just like Java which will increase adoption of Objective-C.
Java 是一种如此流行的语言。我们的方括号吓坏了 Java 程序员。让我们用点符号来取代方括号吧;这样看起来就像 Java 了,这样就能提高 Objective-C 的采用率。
但在接触 Objective-C 之前,我并不是一名 Java 开发人员。我是一名 C++ 开发人员。而且是用 C++(几乎是 C 的超集)。
foo.bar = 10;
foo
可以是一个类、一个结构体或一个联合体,但无论如何,这都是成员访问。
但是,对象如何访问自己的成员呢?在 C++ 中,您可以编写
this->qux = 10;
但更常见的做法是省略 this->
,直接写成
qux = 10;
因为 qux
是一个具有类作用域的成员变量。
现在来看看 Objective-C。在点符号这个邪恶的新大陆上,你经常会看到这样的情况:
self.qux = 10;
其中 qux
是一个属性。一个典型的 Objective-C 新手错误就是说:"好吧,这个 self.
是多余的",然后把它改成这样:
qux = 10;
编译和运行都没有任何问题。那么,有什么值得大惊小怪的呢?
问题在于,在前一种情况下,我们是向 qux
方法发送信息。而在后一种情况下,我们是直接给 qux
实例变量赋值。这是两种截然不同的情况!对于标量,这可能无关紧要,但对于对象,尤其是在编写正确的内存管理时,这就大不相同了。
现在看看如果不使用点符号号会怎样:
[self setQux:10];
没有歧义。这显然是一条消息。
3、点符号助长了违反 "得墨忒耳定律(Law of Demeter) "的行为
你经常看到这样的代码吗?你多长时间写一次?
foo.bar.baz.qux = 10;
这有什么问题吗?让我重写一下,去掉 .
,让信息更明确:
[[[foo bar] baz] setQux:10];
那些抱怨方括号符号 "看起来怪怪的 "的人,会举出这样的例子来说明方括号符号有多难读。
问题是,无法阅读是有原因的:它违反了 "德墨忒尔定律"。
如果你对 "德墨忒尔定律 "还不熟悉,它是指让物体之间过于熟悉,从而污染了物体之间的清晰界限。这里有一个快速记忆的方法:你可以挑你的朋友。你可以挖鼻子。但你不能挖你朋友的鼻子。
所有这些拼凑在一起的括号都是一个线索,表明你可能在不属于你的地方(你朋友的鼻子里)窥探。这是一种代码气味,表明责任可能放错了地方。但现在,圆点符号可以让你继续使用这种臭烘烘的违规行为,而且看起来还不错!
轮到你了!
由于我看到的几乎所有 Objective-C 代码都使用点符号,我意识到自己在逆流而行。好吧,除非你算上几个大腕,比如 Big Nerd Ranch 和 Cocoa Is My Girlfriend。
问题: 同意吗?同意吗?不同意?您怎么看?请在下面留言。
但也请参阅我的后续文章《我接受的点符号...》
译自 Jon Reid 的 Is Dot Notation in Objective-C 100% Pure Evil?
侵删