第4条:多用类型常量,少用#define预处理指令
1. 用#define预处理指令定义常量
#define ANIMATION_DURATION 0.3;
解释:常量没有类型信息,并且其含义不明确。此外,在预处理过程中会把碰到的所有ANIMATION_DURATION一律替换成0.3。
2. 类型常量
static const NSTimeInterval kAnimationDuration = 0.3;
解释:这种方式定义的常量包含类型信息,且清楚地描述了常量的含义。
3.类型常量的命名
3.1 常量局限于某“编译单元”(即实现文件)
若不打算公开某个常量,则应将其定义在使用该常量的实现文件里。
如:
static const NSTimeInterval kAnimationDuration = 0.3;
- 如果试图修改由const修饰符所声明的变量,那么编译器就会报错。
- 而static修饰符则意味着该变量仅在此变量的编译单元中可见。如果声明此变量时不加static,则编译器会为它创建一个“外部符号”(external symbol)。此时若是在另外一个编译单元中也声明了同名变量,那么编译器就抛出错误信息。
实际上,如果一个变量既声明为static,又声明为const,那么编译器根本不会创建符号,而是会像#define预处理指令一样,把所有遇到的变量都替换为常值。
3.2 常量在类之外可见
有时候需要对外公开某个常量。最常见的例子是:用字符串来表示通知的名称,并将其声明为一个外界可见的常值变量。这样,只需以常量变量来注册自己想要接收的通知即可。
此类常量需放在“全局符号表”(global symbol table)中,以便可以在定义该常量的编译单元之外使用。
如:
/* 头文件 “声明” */
extern NSString *const EOCLoginManagerDidLoginNotification;
/* 实现文件 “定义” */
NSString *const EOCLoginManagerDidLoginNotification = @"EOCLoginManagerDidLoginNotification";
- 注意const修饰符在常量类型中的位置。对此的解读是“一个常量,而这个常量是指针,指向NSString对象”。
- extern关键字会告诉编译器:在全局符号表中将有一个名叫EOCLoginManagerDidLoginNotification的符号。换言之,编译器无须查看其定义,即允许代码直接使用此常量。
- 此类常量必须要定义,而且只定义一次。通常,将其定义在与声明该常量的头文件相关的实现文件里。注意,该常量所指向的字符串的存储空间被分配在“数据段”(data section)中。
- 此类常量的命名最好是用与之相关的类名做前缀。
这样,所定义的常量要优于使用#define预处理指令。因为编译器会确保常量值不变。
要点
- 不要用预处理指令定义常量。这样定义出来的常量不含类型信息,编译器只是会在编译前据此执行查找与替换操作。即时有人重新定义了常量值,编译器也不会产生警告信息,这将导致应用程序中的常量值不一致。
- 在实现文件中使用static const来定义“只在编译单元内可见的常量”(translation-unit-specific constant)。由于此类常量不在全局符号表中,所以无须为其名称加前缀。
- 在头文件中使用extern来声明全局常量,并在相关实现文件中定义其值。这种常量要出现全局符号表中,所以其名称应加以区隔,通常用与之相关的类名做前缀。
原文地址:https://blog.csdn.net/qq_24252589/article/details/129913266
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_13677.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。