Objective-c的点符号(.)的奇怪之处

最近在学习Objective-c,发现我对OC中的点符号非常困惑,特别是在学习了**属性(@property)**以后。带着困惑,我搜索了一些关于点符号(.)与箭头符号(->)关系的讨论,并发现了这样一篇文章《Is Dot Notation in Objective-C 100% Pure Evil?》。这篇文章认为点符号是OC中的"坏味",它导致了一系列的混淆并且违反了迪米特法则,应该避免使用它。这篇文章解释了我的部分疑惑,我将翻译出来和大家一起分享作者的观点,废话不多说,上译文。

Objective-C中的点符号是100%纯粹的邪恶吗?

用点符号来发送消息不是一种Objective-c代码异味。但我告诉你,它是邪恶的。

好吧,这太夸张了。我确实在设法与用点符号的项目共存,但是我自己不会用点符号写代码。以下是我在代码中避免使用点符号的3个原因:

1. 点符号会将对象与结构体混淆

看下面代码,告诉我它在干嘛?

foo.bar = 10;

在C语言中,显而易见:foo不是结构体(struct)就是联合(union),foo变量中的bar被赋予了10。

本质上,编译器编写代码来计算foo中的内存偏移量,然后将值10写入计算机地址的寄存器中。非常快速轻巧。

Objective-c 是C的严格超级,那么所有这些都应该可以用在Objective-c的代码中。

2. 点符号模糊了消息传递

因为点符号一种消息传递的语法糖,因此你可以像下面这样写代码:

NSMutableArray *a = NSMutableArray.array;

当然,这太太太邪恶了。为什么呢?“因为array不是一个属性,而是一个方法”。那么,是否使用点符号或者方括号取决于该东西是否是属性?但是这同时又是消息传递!为什么要添加第二种消息传递语法?

在Objective-c中添加了点符号,苹果公司的人说:“Java是一种流行的语言。我们的方括号吓坏了Java程序员。让我们用点代替方括号,它看起来就像Java一样,这样能够增加Objective-c的使用率”。

但是在使用Objective-c之前,我不是一名Java开发人员。我是一名C++开发人员。在C++中(C++几乎就是C的超集)

foo.bar = 10;

这是在访问成员变量。foo可以是类,结构题或者联合,无论是啥,上面这行代码都只是访问变量。

但是一个对象如何在内部访问它的成员呢?在C++中,你可以这样写:

this->qux = 10;

但是通常可以省略this和->

qux = 10;

因为在类的作用域中,qux是一个成员变量。

现在我们来看看Objective-c,在点符号的邪恶领域中,你经常可以看到这个:

self.qux = 10;

其中,qux是一个属性。一个Objective-c新手常放的错误就是说,“好吧,这个点是多余的”,并改为:

qux = 10;

这编译并运行没有任何问题,那么大惊小怪的是什么?

问题在于,前一种情况(self.qux=10),我们发送一个消息到qux方法中。在后一种情况(qux=10),我们直接对qux实例变量进行赋值。这是两种天壤之别的操作!对于标量来说,这可能不重要,但是它会对对象产生巨大的影响,特别是对编写正确的内存管理。

现在我们来看看如果不用点操作应该如何写

[self setQux:10];

这就消除了歧义。这很明显是消息传递。

3. 点符号违反了迪米特法则

你经常看到这样的代码吗?你多久写一次?

foo.bar.baz.qux = 10;

这代码有什么问题?让我在没有点符号的情况重写它,显示使用消息传递:

[[[foo bar] baz] setQux:10];

那些抱怨方括号看起来很奇怪的人总是用这样的例子以表明它是多么的难以理解。

这样的代码不可读,只因为:它违反了迪米特法则。

如果你不熟悉迪米特法则,那就是通过让对象间变得过于熟悉来污染对象间的清晰边界。这里有一个快速记住它的方法:你可以选择你的朋友,你可以抠你的鼻子,但是你不能抠你朋友的鼻子。

所有那些集中的括号都是一条线索,你可能会在不属于你的地方抠鼻子。这种责任的错位,就是代码坏味。但是现在,点符号可以使用这种违规的行为,并且看起来很好!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值