摒弃:
#define ANIMATION_DURATION 0.3
 
#define ERROR_MESSAGE @“ErrorMessage”
1)没有常量的类型信息
2)假设此指令声明在某个头文件中,那么所有引入了这个头文件的代码,都可以访问和修改ANIMATION_DURATION。
 
推荐:
1、私有常量
.m文件
static const NSTimeInterval kAnimationDuration = 0.3;
 
static NSString *const kErrorMessage = @“ErrorMessage”;
 
2、公开常量
.h文件
extern const NSTimeInterval PersonModelAnimationDuration;
 
extern NSString *const PersonModelErrorMessage;
 
.m文件
const NSTimeInterval PersonModelAnimationDuration = 0.3;
 
NSString *const PersonModelErrorMessage = @“ErrorMessage”;
 
几点说明:
1、常量名称的常用命名方法:若常量局限于某“编译单元”,也就是“实现文件”之内,则在前面加字母k;若常量在类之外可见,则通常以类名为前缀。
 
2、在头文件里声明预处理指令来定义常量,这样做真的非常糟糕,当常量名称有可能互相冲突时更是如此。
 
3、私有变量一定要同时使用static与const来声明。如果试图修改由const修饰符所声明的变量,那么编译器就会报错。而static修饰符则意味着该变量仅在定义此变量的编译单元中可见。编译器每收到一个编译单元,就会输出一份“目标文件(object file)”在Objective-C的语境下,“编译单元”一词通常指每个类的实现文件(以.m为后缀名)。因此,在上述范例代码中声明的kAnimationDuration变量,其作用域仅限于由PersonModel.m锁生成的目标文件中。假如声明此变量时不加static,则编译器会为它创建一个“外部符号”。此时,若是另一个编译单元中也声明了同名变量,那么编译器就会抛出一条错误消息。
 
4、事实上,如果一个变量既声明为static,又声明为const,那么编译器根本不会创建符号,而是会像#define预处理指令一样,吧所有遇到的变量都替换为常量。不过,区别是,用这种方法定义的常量是带有类型信息的。
 
5、全局常量需要放在“全局符号表”中,以便可以在定义该常量的编译单元之外还用。因此全局常量是会创建符号的。
 
6、extern这个关键字是要告诉编译器,在全局符号表中将会有一个名为***的符号。也就是说,编译器无须查看其定义,即允许代码使用此常量。因为它知道,当链接成二进制文件之后,肯定能够找到这个常量。因此,此类常量必须定义,而且只能定义一次。通常将其定义在与声明该常量的头文件相关的实现文件里。
 

多用类型常量,少用#define预处理指令的更多相关文章

  1. Effective Objective-C 2.0 — 第四条:多用类型常量,少用#define预处理指令

    第四条:多用类型常量,少用#define预处理指令 使用#define 预处理的坏处:定义出来的常量没有类型信息,编译器只是会在编译前据此执行查找与替换操作.即使有人重新定义了常量值,编译器也不会产生 ...

  2. 52个有效方法(4) - 多用类型常量,少用#define预处理指令

    局部常量 在实现文件中使用 static const 来定义"只在编译单元内可见的常量"(translation-unit-specific constant).其命名规则为在前面 ...

  3. 第4条:多用类型常量,少用#define预处理指令

    定义常量的几种方式: 1.#define ANIMATION_DURAION 0.3         //定义了一个动画时长的常量, 预处理过程会把碰到的所有ANIMATION_DURAION一律替换 ...

  4. C语言中的#define预处理指令

    本文链接:http://www.cnblogs.com/xxNote/p/4009460.html 今天看C Primer Plus里面看449页里面 16.2.1语言符号 讲到从技术方面看,系统把宏 ...

  5. 关于#define预处理指令的一个问题

    背景:由于经常需要在远程服务端和测试服务端进行切换,所以将接口的地址定义为了一个预处理变量,例如 //#define APIDOMAIN @"http://10.0.0.2" #d ...

  6. C/C++预处理指令#define,#ifdef,#ifndef,#endif…

    2016年12月29日更新: 今天查看以前文件的时候, 突然发现了#error 这个预处理指令.然后回想一下工作, 发现这个指令使用场景还是很多的.比如: 一个项目的模块儿之多,源文件之大,代码之多, ...

  7. C/C++预处理指令#define,#ifdef,#ifndef,#endif… (转)

    本文转自博文C/C++预处理指令#define,#ifdef,#ifndef,#endif….这篇博文写得特别好,特转载. 本文主要记录了C/C++预处理指令,常见的预处理指令如下: #空指令,无任何 ...

  8. C/C++预处理指令#include,#define,#undef,#if,#ifdef,#ifndef,#elif,#endif,#error......

    本文主要记录了C/C++预处理指令,常见的预处理指令如下: #空指令,无任何效果 #include包含一个源代码文件 #define定义宏 #undef取消已定义的宏 #if如果给定条件为真,则编译下 ...

  9. C/C++预处理指令#define,条件编译#ifdefine

    本文主要记录了C/C++预处理指令,常见的预处理指令如下: #空指令,无任何效果 #include包含一个源代码文件 #define定义宏 #undef取消已定义的宏 #if如果给定条件为真,则编译下 ...

随机推荐

  1. devexpress layoutview

    1.设定数据源 2.设置view 3.设置 templat cardview 4 显示

  2. Operating systems Chapter 4

    There are two processes to switch, when one run:io instruction, switch on other process. After ios, ...

  3. php redis 集群扩展类文件

    <?php /** * redis集群驱动 */ namespace Common\Api; class RedisCluster{ protected $servers=array( '192 ...

  4. Plastic Sprayers Manufacturer - Ingenious Design Of Spray Plastic Bottle

    Plastic bottles are now an indispensable container in life. Plastic bottles will appear in all aspec ...

  5. 内存泄漏与weakMap、weakSet

    “DOM 引用造成内存泄露”这一点我们可以使用WeakMap或者WeakSet存储DOM节点,DOM被移除掉WeakMap或者WeakSet内部的DOM引用会被自动回收清除 https://jueji ...

  6. UDLD(Unidirectional Link Detection)

    1.UDLD(单向链路检测协议)工作原理          为了在生成转发环路之前检测到单向链路,Cisco 设计并实施了 UDLD 协议.UDLD 是与第 1 层 (L1) 机制一起工作以确定链路物 ...

  7. JS获取光标在input 或 texterea 中下标位置

    <textarea placeholder="请输入表达式" id="methodInput" ></textarea> 获取位置: v ...

  8. [ DLPytorch ] 文本分类&图像增强

    图像增强 图像增广(image augmentation)技术通过对训练图像做一系列随机改变,来产生相似但又不同的训练样本,从而扩大训练数据集的规模.图像增广的另一种解释是,随机改变训练样本可以降低模 ...

  9. matlab练习程序(传染病模型)

    最近新型冠状病毒疫情越来越严重了,待在家中没法出去,学习一下经典传染病模型. 这里总结了五个模型,分别是SI模型,SIS模型,SIR模型,SIRS模型,SEIR模型. 这几种模型的特点先介绍一下. 首 ...

  10. php 安装 swoole

    1.安装swoole cd /usr/local/src wget https://github.com/swoole/swoole-src/archive/v1.9.1-stable.tar.gz ...