天天看点

《编写高质量代码:改善Objective-C程序的61个建议》——建议3:尽量使用const、enum来替换预处理#define

本节书摘来自华章出版社《编写高质量代码:改善objective-c程序的61个建议》一 书中的第1章,第1.3节,作者:刘一道,更多章节内容可以访问云栖社区“华章计算机”公众号查看。

<code>#define</code>定义了一个宏,在编译开始之前就会被替换。const只是对变量进行修饰,当试图去修改该变量时,编译器会报错。在一些场合里你只能用 #define,而不能用 const。理论上来说,const 不仅在运行时需要占用空间,而且还需要一个内存的引用;但从时间上来说,这是无关紧要的,编译器可能会对其进行优化。

const在编译和调试的时候比 #define 更友好。在大多数情况下,当你决定用哪一个时,这是你应该考虑的一个非常重要的点。

想象一下,下面这样一个应该使用 #define 而不是 const 的场景:如果想在大量的 .c 文件中使用一个常量,只需要使用 #define 放在头文件中;而使用 const,则需要在 .c 文件和头文件中都进行定义,如下所示。

my_int_const ,在任何 c 文件中都不能当作一个静态变量或全局作用域使用,除非它已被定义。然而,对于一个整型常量,你可以使用枚举(enum)。事实上,这就是 apple一直在做的事情。它(enum)兼有 #define 和 const 的所有优点,但是只能用在整型常量上。

哪一个更高效或更安全呢?#define 在理论上来说更高效,但就像之前说的那样,在现代的编译器上,它们可能没什么不同。#define 会更安全,因为当试图赋值给它时,总会出现一个编译器错误。

因此,相对字符串字面量或数字,更推荐适用常量。应使用static方式声明常量,而非使用#define的方式来定义宏。

恰当用法如下所示:

不当用法如下所示:

对于整型类型,代替#define比较好的方法是使用enum,在使用enum时,推荐使用最新的fixed underlying type规范的ns_enum和ns_options宏,因为它们是基于c语言的枚举,保留了c语言的简洁和简单的特色。这些宏能明确指定枚举类型、大小和选项,改善在xcode中的代码质量。此外,在旧的编译器中,这种语法声明能正确编译通过,在新的编译器中也可明解基础类型的类型信息。

下面,使用ns_enum宏定义枚举。该组值是互斥的,代码如下:

在本例中,在命名uitableviewcellstyle的nsinteger类型时,通过使用ns_enum宏使界定双方的名称和枚举类型更容易了。

在下面的代码中,通过使用ns_options宏定义了一组可以组合在一起的位掩码值,实现方式如下:

像枚举一样,ns_options宏定义了一个名称和一个类型。然而,对于选项的类型通常应该是nsuinteger 。

在实际编码中,如何使用枚举宏来更换enum,比如这样一个enum定义:

在实际开发中,经常会使用enum来定义一个位掩码,如下面一个用enum来定义位掩码的示例:

对于上面的通过用enum定义位掩码的示例,可使用ns_options宏实现如下:

或者,也可以使用现代化的objective-c的转换器在xcode自动进行此更改。

《编写高质量代码:改善Objective-C程序的61个建议》——建议3:尽量使用const、enum来替换预处理#define

继续阅读