《iOS 三问》--#define 用法大全
OC 的 #define
命令与在 C 语言中的非常相似,是一个预处理命令,其作用是在编译之前对你的代码进行预处理,使用在 define
中定义的字符串 value 来替换你要替换的字符串 key, 其形式如:
1 |
这里要注意几点:
#define 预处理命令
顾名思义,是在编译前工作的,所以其优先高于各种编译期间指令,而且享受不到编译器强大的错误提示(所以使用它要格外小心);- 像上面**#define 使用格式**,要注意你的 key 与 value 都不要有空格(除非是字符串用引号括住了);
- KEY 一般使用全大写加下划线组合,至少首字母要大写,这样别人在代码人能一眼看出这是个宏。
1 基本使用
我们一般会这样使用,比如在一个头文件中声明
1 | #define PI 3.141592654 |
到后面要使用圆周率时,就不需要每次都使用 3.141592654 这个魔术数字,直接使用 PI 就行,如 perimeter = 2 * PI * raiuds;
1.1 括号问题
使用 define
时,我们建议 value 一般要加上括号,以避免因替换环境引起的错误,如
1 |
|
上面的语句发生错误,本来我们希望的是: viewWidth = (20 + 10) * 2 = 60;
结果被展开成:viewWidth = 20 + 10 * 2 = 40;
所以,使用 define 时,value 处最好都加上括号:
1 |
2 条件 define
define 还可以用于在编译之前做一个条件判断,在编译前,预处理会进行判断,把不符合条件的代码段屏蔽掉。比如我们常用的
1 |
这里就作了一个条件判断,如果在之前使用 #define DEBUG
定义过 DEBUG 这个宏,就保留 if 块中的代码;否则,保留 else 块中的代码。
3 高级使用
3.1 define 函数 - 宏方法
#define 声明中还可以使用参数,并且可使用多个参数;这一特性被称为 “宏方法”:
1 |
|
特别注意括号问题,上面的别写成 #define SQUARE (x) ( x * x )
,原因自己想。
3.2 多个参数的宏方法
如果参数中有多个参数,可以在 key 中使用 ...
来传入多个参数,在 value 中使用 ##__VA_ARGS__
来引用传入的参数。如下面的一个便利新建数组的宏方法:
1 |
|
3.3 #算符以及 ## 算符
# 算符
可产生一个 C - 语言 格式的字符串(这个在 OC 中用得比较少)。如:
1 |
|
# 算符
用来连接两段字符串。假设你有一组变量,x1 到 x100。如果你想打印其中某一个变量的值。你可以这样定义:
## 算符
可以直接生成复合的变量名!如:
1 |
|
其实,## 最常用的用途还是上面介绍的 ##__VA_ARGS__,它可用来抓取省略号所代表的所有内容。
3.4 使用 \
切分多行宏定义
比如我们常用的 weakify 与 strongify 字义
1 |
4 编程中常用的宏
4.1 表示在模块器中
1 |
4.2 根据 target 条件编译
可以在项目的 Build Settings
中的 Preprocessor Macros
中设置 target 的预编译宏。然后就可以使用下面的代码来根据不同的 target 跑不同的代码了(一般用于配置)。
1 |