类型化常量 (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 方法的更多相关文章

  1. Microsoft Visual C++ 6.0预处理器参考手册

    返回总目录 Microsoft Visual C++ 6.0 预处理器参考手册 目录引言........................................................ ...

  2. C#变量、常量、枚举、预处理器指令知多少

    一.变量 C#共有其中变量类型有:静态变量.实类变量.数组元素.数值参数.引用参数.输出参数和局部变量 先定义一个简单的类来说明,如下: public class VariableDefine { p ...

  3. C Primer Plus之C预处理器和C库

    编译程序前,先由预处理器检查程序(因此称为预处理器).根据程序中使用的预处理器指令,预处理器用符号缩略语所代表的内容替换程序中的缩略语. 预处理器不能理解C,它一般是接受一些文件并将其转换成其他文本. ...

  4. C和指针 (pointers on C)——第十四章:预处理器

    第十四章 预处理器 我跳过了先进的指针主题的章节. 太多的技巧,太学科不适合今天的我.但我真的读,读懂.假设谁读了私下能够交流一下.有的小技巧还是非常有意思. 预处理器这一章的内容.大家肯定都用过.什 ...

  5. C学习笔记(9)--- 预处理器,头文件

    1.预处理器: 预处理器不是编译器的组成部分,但是它是编译过程中一个单独的步骤.简言之,C 预处理器只不过是一个文本替换工具而已,它们会指示编译器在实际编译之前完成所需的预处理. 我们将把 C 预处理 ...

  6. Docs-.NET-C#-指南-语言参考-预处理器指令:#if 预处理指令

    ylbtech-Docs-.NET-C#-指南-语言参考-预处理器指令:#if 预处理指令 1.返回顶部 1. #if(C# 参考) 2018/06/30 如果 C# 编译器遇到 #if 指令,最终是 ...

  7. 《你必须知道的495个C语言问题》读书笔记之第8-10章:字符串、布尔类型和预处理器

    一.字符和字符串 1. Q:为什么strcat(string, '!')不行? A:strcat()用于拼接字符串,所以应该写成strcat(string, "!")." ...

  8. C和指针 第十四章 预处理器 头文件

    编写一个C程序,第一个步骤称为预处理,预处理在代码编译之前,进行一些文本性质的操作,删除注释.插入被include的文件.定义替换由#define定义的符号,以及确定代码的部分内容是否应该按照条件编译 ...

  9. C语言--- 字符串数组 、 预处理器和预处理指令 、 多文件编程 、 结构体

    1 输入一个姓名,判断是否是五虎上将. 1.1 问题 本案例需要使用交互的方式判断:用户从控制台输入一个名字,由程序判断该名字是否在五虎上将的名单中.五虎上将的名单是:GuanYu.ZhangFei. ...

随机推荐

  1. LeetCode 113. Path Sum II 动态演示

    给第一个目标值,返回一棵树从根到叶子所有和等于目标值的路径. 经典的深度优先算法 /** * Definition for a binary tree node. * struct TreeNode ...

  2. U盘修复教程--使用量产工具和芯片检测工具

    U盘修复教程(金士顿DT101) 本教程使用量产工具(量产可理解为强制恢复出厂设置),量产有风险(U盘彻底报废),根据教程所造成所有损失均与本文作者无关. ·第一步:下载ChipGenius_v4_0 ...

  3. Tensorflow--Keras官方原文

    Keras 是一个用于构建和训练深度学习模型的高阶 API(应用程序接口).它可用于快速设计原型.高级研究和生产,具有以下三个主要优势: 方便用户使用 Keras 具有针对常见用例做出优化的简单而一致 ...

  4. sshpass非交互SSH密码验证

    1.yum安装yum install sshpass -y1.1编译安装yum install wget -ywget http://sourceforge.net/projects/sshpass/ ...

  5. Java 小技巧和在Java避免NullPonintException的最佳方法(翻译)

                前几天就g+里面看到有人引用这篇博文.看了一下.受益颇多. 所以翻译过来,希望和大家一起学习.本人英语水平有限,假设有错,请大家指正. 原文地址(须要翻墙):http://ja ...

  6. 自己做的html5手机站点

    这个站点採用html5+css3+jquerymobile 仅仅开发了前台的功能,前台的界面比較美观,后端不方便放上,各位有空能够自己开发这个站点的界面有參考各个菜谱站点的页面的样式,可是又不一样,是 ...

  7. linux 日常学习

    杀掉进程 ps aux |grep caddy axy5418+ 14186 0.0 1.7 117032 10372 ? Sl 02:17 0:00 caddy axy5418+ 14332 0.0 ...

  8. jquery+ajax获取本地json对应数据

    首先,记得导入jquery.js文件. json内容: var obj123=[        {"option":"2,3,9,14,19,24,32",&q ...

  9. 微信小程序(16)-- bindtap,catchtap事件绑定的区别

    bindtap,catchtap事件绑定的区别,这里就涉及冒泡事件了.bind事件绑定不会阻止冒泡事件向上冒泡,catch事件绑定可以阻止冒泡事件向上冒泡. logs.wxml <view cl ...

  10. squid代理与缓存(上)

    squid代理与缓存(上) 1. Squid介绍 1.1 缓存服务器介绍 缓存服务器(英文意思cache server),即用来存储(介质为内存及硬盘)用户访问的网页,图片,文件等等信息的专用服务器. ...