尽量用类型化的常量替代预处理器的 #DEFINE 方法
类型化常量 (TYPED CONSTANTS)
#define ANIMATION_DURATION 0.3
这是一个预处理器指令,当编译器在代码中发现有 ANIMATION_DURATION 时,就将它替换为 0.3,编译器不知道这个字符串所指代的数值属性。 更好的办法是用常量去替代预处理器定义:
static const NSTimerInterval kAnimationDuration = 0.3
这样清楚地定义了这个常量是什么,类型是 NSTimerInterval。他可以使阅读代码的人容易理解。注意常量的命名,加前缀 k 表示在本地单元(.m)中适用。如果要在外部使用这个常量,应该加上当前class的名字作为前缀:
EOCViewClassAnimationDration
把常量定义在 .h 中是非常不好的实践。
重点是同时声明 static 和 const。const 限定它不能被修改。static 限定定义这个变量所在的转换单元(translation unit)。Objective-C中,每个class(.m文件)有一个转换单元。 如果变量未声明 static,编译器会为它生成一个外部符号。如果其他的转换单元声明了同样名字的变量,程序会报错。
实际上,当用 static 和 const 去定义一个变量时,编译器不只是像 #define 那样去盲找和替换。至少它显现了所属的类型信息。
有时候你想让一个常量暴露在外部,应该这样定义:
//在 .h 中
extern NSString *const EOCStringConstant;
//在 .m 中
NSString *const EOCStringConstant = @"VALUE";
.h 中的关键词 extern 告诉编译器在全局符号表中有一个 EOCStringConstant。意思是编译器可以使用这个常量,只知道它存在于所链接到的二进制文件中,但不必知道它是怎样定义。
这样定义编译器知道这个值不能被更改,并且这个值会被到处使用。
记住
避免预处理器定义。它们不包含类型信息,只是在编译前执行查找替换。它们可以在没有警告下被重新定义,产生不一样的值。
在实现文件中定义转换单元常量如 static const。这些常量不会暴露给全局符号表,因此它们的名字不需要命名空间。
定义全局常量在.h文件中,然后在.m中定义它们的值。这些常量会出现在全局符号表(global symbol table)中,因此它们的名字应该有命名空间,通常以class命为前缀表示。
尽量用类型化的常量替代预处理器的 #DEFINE 方法的更多相关文章
- Microsoft Visual C++ 6.0预处理器参考手册
返回总目录 Microsoft Visual C++ 6.0 预处理器参考手册 目录引言........................................................ ...
- C#变量、常量、枚举、预处理器指令知多少
一.变量 C#共有其中变量类型有:静态变量.实类变量.数组元素.数值参数.引用参数.输出参数和局部变量 先定义一个简单的类来说明,如下: public class VariableDefine { p ...
- C Primer Plus之C预处理器和C库
编译程序前,先由预处理器检查程序(因此称为预处理器).根据程序中使用的预处理器指令,预处理器用符号缩略语所代表的内容替换程序中的缩略语. 预处理器不能理解C,它一般是接受一些文件并将其转换成其他文本. ...
- C和指针 (pointers on C)——第十四章:预处理器
第十四章 预处理器 我跳过了先进的指针主题的章节. 太多的技巧,太学科不适合今天的我.但我真的读,读懂.假设谁读了私下能够交流一下.有的小技巧还是非常有意思. 预处理器这一章的内容.大家肯定都用过.什 ...
- C学习笔记(9)--- 预处理器,头文件
1.预处理器: 预处理器不是编译器的组成部分,但是它是编译过程中一个单独的步骤.简言之,C 预处理器只不过是一个文本替换工具而已,它们会指示编译器在实际编译之前完成所需的预处理. 我们将把 C 预处理 ...
- Docs-.NET-C#-指南-语言参考-预处理器指令:#if 预处理指令
ylbtech-Docs-.NET-C#-指南-语言参考-预处理器指令:#if 预处理指令 1.返回顶部 1. #if(C# 参考) 2018/06/30 如果 C# 编译器遇到 #if 指令,最终是 ...
- 《你必须知道的495个C语言问题》读书笔记之第8-10章:字符串、布尔类型和预处理器
一.字符和字符串 1. Q:为什么strcat(string, '!')不行? A:strcat()用于拼接字符串,所以应该写成strcat(string, "!")." ...
- C和指针 第十四章 预处理器 头文件
编写一个C程序,第一个步骤称为预处理,预处理在代码编译之前,进行一些文本性质的操作,删除注释.插入被include的文件.定义替换由#define定义的符号,以及确定代码的部分内容是否应该按照条件编译 ...
- C语言--- 字符串数组 、 预处理器和预处理指令 、 多文件编程 、 结构体
1 输入一个姓名,判断是否是五虎上将. 1.1 问题 本案例需要使用交互的方式判断:用户从控制台输入一个名字,由程序判断该名字是否在五虎上将的名单中.五虎上将的名单是:GuanYu.ZhangFei. ...
随机推荐
- tp 框架目录结构
ThinkPHP是为了简化企业级应用开发和敏捷WEB应用开发而诞生的.最早诞生于2006年初,2007年元旦正式更名为ThinkPHP,并且遵循Apache2开源协议发布.ThinkPHP从诞生以来一 ...
- Linux 内核剖析
https://www.ibm.com/developerworks/cn/linux/l-linux-kernel/ 由于本文的目标是对 Linux 内核进行介绍并探索其体系结构和主要组件,因此首先 ...
- Marriage Match II 【HDU - 3081】【并查集+二分答案+最大流】
题目链接 一开始是想不断的把边插进去,然后再去考虑我们每次都加进去边权为1的边,直到跑到第几次就没法继续跑下去的这样的思路,果不其然的T了. 然后,就是想办法咯,就想到了二分答案. 首先,我们一开始处 ...
- python装饰器(基础中的重点)
一.简单的装饰器 1.为什么要使用装饰器呢? 装饰器的功能:在不修改原函数及其调用方式的情况下对原函数功能进行扩展 装饰器的本质:就是一个闭包函数 那么我们先来看一个简单的装饰器:实现计算每个函数的执 ...
- dp(最长升序列:二分查找时间优化nlogn)
We are all familiar with sorting algorithms: quick sort, merge sort, heap sort, insertion sort, sele ...
- Solr的学习使用之(一)部署
Solr的主要功能是全文检索,该功能分为两个过程:创建索引和对索引进行搜索 一.心得体会 第一次写技术博客,这次写的基本上都是从网络上整理的来的,外加自己的一些实践,以后争取全部原创哈,都说写技术博客 ...
- Java Predicate
Predicate 接口说明 /* * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. * O ...
- vue下超级滚动条perfect-scrollbar(在特定框架里使用一款并非为该框架定制的库/插件)
点我查看
- python进行两个大数相加
python进行两个大数相加:由于int类型32位或64位都有长度限制,超出会内存溢出,无法计算,那么解决方法如下: 思路: 1.将超长数转换成字符串 2.进行长度补零,即让两个要计算的字符串长度一样 ...
- 【串线篇】Mybatis缓存之二级缓存
1.应用 二级缓存:namespace级别的缓存:SqlSession关闭或者提交以后有效 一级缓存:SqlSession关闭或者提交以后,一级缓存的数据会放在二级缓存中: 二级缓存的使用:mybat ...