宏
宏分为普通宏和枚举宏,下面我们分别看一下
一、普通宏
对象宏
对象宏也就是我们常用的定义一些简单的常数的宏,在编译阶段编译器在语义分析时,会进行替换将宏展开。
#define M_PI 3.1415
函数宏
函数宏类似于我们定义的普通函数,它是可以接收参数,并返回目标结果的宏
实现MIN的宏:实现一个函数,输入两个参数,输出比较小的数。
版本一
#define MIN(A,B) A < B ? A : B
使用一:
int mini = MIN(1,2);
替换 mini = 1 < 2 ? 1 : 2;
结果 mini = 1,正确
使用二:
int mini = 2 * MIN(3,4)
替换 mini = 2 * 3 < 4 ? 3 : 4
结果 mini = 4,错误,原因是宏直接替换
--->可以看到将()即可,于是改为
#define MIN(A,B) (A < B ? A : B)
输入上面的例子,替换后变为mini = 2 * (3 < 4 ? 3 : 4)
使用三:
int mini = MIN(3, 4 < 5 ? 4 : 5);
替换 mini = (3 < 4 < 5 ? 4 : 5 ? 3 : 4 < 5 ? 4 : 5)
= (3 < (4 < 5 ? 4 : 5 )? 3 : 4) < 5 ? 4 : 5)//三目运算符从左向右计算
= int a = ((3 < 4 ? 3 : 4) < 5 ? 4 : 5)
= int a = (3 < 5 ? 4 : 5)
= int a = 4,错误,因为你在展开之后运算受三目运算符影响,导致异常
使用四:
float a = 1.0f;
float mini = MIN(a++, 1.5f);
替换 mini = (a++ < 1.5f ? a++ : 1.5f)
= 3,错误,原因宏展开导致了a++被多执行,不是我们预想的只执行一次,比较a++和1.5f的时候,先取1和1.5比较,然后a自增1。接下来条件比较得到真以后又触发了一次a++,此时a已经是2,于是b得到2,最后a再次自增后值为3。
在宏里面如果一行太长,可以在回车前添加反斜杠\,不影响宏定义
二、枚举的宏
一、简介
NS_ENUM和NS_OPTIONS宏提供了一种简明、简单的方法来定义基于C语言的枚举和选项。 这些宏提高了Xcode中的代码完成性,并明确指定了枚举和选项的类型和大小。 此外,此语法以一种方式来声明枚举,该方式由旧编译器正确地计算,并且由更新的编译器来解释底层类型信息。 使用NS_ENUM、NS_OPTIONS宏定义枚举,有助于定义枚举的名称和类型;
如果需要以按位或操作来组合的枚举都应该使用NS_OPTIONS宏;若枚举不需要互相组合,可以使用NS_ENUM来定义
二、例子
(1)如果使用枚举定义UITableViewCellStyle,可以使用NS_ENUM宏来改写
enum{
UITableViewCellStyleDefault,
UITableViewCellStyleValue1,
UITableViewCellStyleValue2,
UITableViewCellStyleSubtitle,
};
typedef NSInteger UITableViewCellStyle;
改写版
typedef NS_ENUM(NSInteger,UITableViewCellStyle){
UITableViewCellStyleDefault,
UITableViewCellStyleValue1,
UITableViewCellStyleValue2,
UITableViewCellStyleSubtitle,
}
(2)使用枚举定义的的一组位掩码。可以使用NS_OPTIONS来改写
enum{
UIViewAutoresizingNone =0,
UIViewAutoresizingFlexibleLeftMargin =1<<0,
UIViewAutoresizingFlexibleWidth =1<<1,
UIViewAutoresizingFlexibleRightMargin =1<<2,
……
}
使用NS_OPTIONS来改写
typedef NS_OPTIONS(NSInteger,UIViewAutoresizing){
UIViewAutoresizingNone =0,
UIViewAutoresizingFlexibleLeftMargin =1<<0,
UIViewAutoresizingFlexibleWidth =1<<1,
UIViewAutoresizingFlexibleRightMargin =1<<2,
……
}