最近在学习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];

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

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

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

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

Objective-c的点符号(.)的奇怪之处相关推荐

  1. php mysql 别名_php和mysql的一些奇怪之处

    今总结一下php和mysql的一些奇怪之处,并且讲一下如何将数据库中的一个字段的值赋给另一个字段,如果原来你不知道,现在一看一定吓你一跳,竟然是如此的简单.php和mysql就像是一对一见钟情.相见恨 ...

  2. 懒人听书:师父关于人们的奇怪之处之谈

    一天一个弟子问师父:您能谈谈人们的奇怪之处吗? 师父说:人们急于成长,然后哀叹失去的童年:人们以健康换取金钱,不久后又想用金钱来换取健康:人们对未来焦虑不已,却又无视现在的幸福:因此,他们既不活在当下 ...

  3. Office Word中回车符号变为奇怪的符号如何修正!

    如 上图,尤其是在Word2007中,回车符的样式变为奇特的形状,有点儿像音乐符号,看起来很不习惯. 想要便会2003版本中的回车符可参照下列的步骤: 1.去开始菜单中找到Microsoft offi ...

  4. WINDOWS下调用GetTokenInformation的奇怪之处--两次调用

    就是用getLastErr可以得到错误号,同时,会将需要的长度写到参数里,再进行第二次调用,以此来节约内存空间. 神奇的长见识了. 相关说法如下: ====================== The ...

  5. UE4无法下断,未添加任何符号

    网上很多方法都处理了,无效.后针对提示:断点不会命中,文件未添加任何符号入手! 在的属性->调试->符号里,将项目Binaries\Win64目录,以及引擎的对应Binaries\Win6 ...

  6. 【SRIO】2、RapidIO串行物理层的包与控制符号

    目录 一.RapidIO串行物理层背景介绍 二.RapidIO串行物理层的包格式 2.1 串行物理层包格式与并行物理层包格式的区别 2.2 RapidIO串行物理层包格式 2.3 RapidIO串行物 ...

  7. 斜度符号标注_机械图纸尺寸标注规则,第1次见,太直观太形象了!测量工程师可以拿去教绘图的了!...

    (一)基本规则 1.机件的真实大小应以图样上所注的尺寸数值为依据,与图形的大小及绘图的准确度无关. 2.图样中(包括技术要求和其它说明)的尺寸,以mm为单位时,不需标注计量单位的代号或名称,如采用其它 ...

  8. MyEclipse调试过程中遇到一个奇怪的问题

    虽然看着别人的代码有些头大,但是咱目标也不高,调通了就成. 为了调试方便,我将Tomcat下配置的应用全都去掉了,想看看Tomcat会不会报错.在启动Tomcat时显示某个应用目录不存在,不是取消全部 ...

  9. 【高速接口-RapidIO】2、RapidIO串行物理层的包与控制符号

    总目录:总目录(经验分享) 献上链接: [高速接口-RapidIO]2.RapidIO串行物理层的包与控制符号 [高速接口-RapidIO]3.RapidIO串行物理层的包传输过程 [高速接口-Rap ...

最新文章

  1. 二位数组的子数组最大值
  2. 去除word文档中向下的箭头图标
  3. Pyhton 模块和包
  4. Spring Boot 2.0.5 配置Druid数据库连接池
  5. SAP Spartacus home page的三大section
  6. 转 php 观察者模式
  7. 详解预训练模型、信息抽取、文本生成、知识图谱、对话系统技术
  8. 【实用】MAC电脑如何进行截图,mac下QQ截图工具的用法
  9. AD15 PCB笔记
  10. jetbrains验证服务器,搭建个人jetbrains授权服务器
  11. 《少有人走的路——心智成熟的旅程》读书笔记
  12. 基于DTU的工业控制组网方案
  13. 一张图+一个Box+一个TextArea带你DIY不一样的数字键盘
  14. 京东云主机 mysql_京东云所有地域正式支持 MySQL 8.0!
  15. RPM包安装的数据库进行版本升级
  16. 零粉丝直播带货,日赚两万是真是假?最新抖音直播玩法!
  17. 分布式系统监控软件——zabbix详解(七) zabbix+ (qqmail 或者 第三方报警平台(睿象云))的 报警实现
  18. 电脑USB插拔记录删除方法分享
  19. uni-app 二维码扫描识别功能
  20. 使用Proxmox搭建私有云平台

热门文章

  1. php final什么意思,php final关键字的应用
  2. python len命令_python命令行参数
  3. linux查看火狐进程,Firefox 终于用上多进程技术了
  4. git 删除tag_Git常用命令
  5. 回溯法 批处理作业调度_不懂调度系统架构,就不要谈银行数据仓库
  6. wifi 2.4g 5g 区别_关于路由器的2.4G以及5G,你不知道的那些事
  7. jmeter jdbc mysql_jmeter获取JDBC响应做接口关联(三)
  8. java gof_java GOF23设计模式-简单工厂模式进阶
  9. jQuery+toggle
  10. 经典解释监视器和对象锁