枚举
真理惟一可靠的标准就是永远自相符合。
一. 枚举的作用和定义
枚举的作用在于规范并语义化的定义代码中的状态、选项等常量。如果一个变量只有几种可能的值,比如屏幕支持的方向只有上(Orientation Portrait)、下(Orientation Upside down)、左(Orientation Landscape Left)、右(Orientation Landscape Right)。就可以使用枚举类型来定义一个代表方向枚举类型变量。
枚举类型的定义以关键字enum开头,之后是枚举数据类型的名称,最后是在一对花括号内的选项标识符序列。 (实现枚举所用的数据类型取决于编译器。除了使用默认类型,还可以指明用何种“底层数据类型”来保存枚举类型的变量):
//使用编译器默认类型
enum Orientation {
Orientation_Portrait,
Orientation_Down,
Orientation_left,
Orientation_Right
};
//指明枚举类型保存变量的类型
enum Orientation: NSUInteger {
Orientation_Portrait,
Orientation_Down,
Orientation_left,
Orientation_Right
};
//定义匿名枚举类型,并定义两个枚举变量
enum {
Orientation_Portrait,
Orientation_Down,
Orientation_left,
Orientation_Right
} WX_Orientation,QQ_Orientation;
枚举类型值的分配原则:编译器会为枚举分配一个独有的编号(枚举变量的本质就是无符号整数(%u占位符)),从0开始,每个枚举递增1。(可以手动指定某个枚举成员所对应的值,接下来的枚举值会在上一个的基础上递增1)。
二. 使用typedef关键字重新定义枚举
使用关键字typedef重新定义枚举,目的是为了简化枚举的声明,不需要每次都写enum
enum Orientation: NSUInteger {
Orientation_Portrait,
Orientation_Down,
Orientation_left,
Orientation_Right
};
typedef enum Orientation Orientation;
//使用Orientation代替完整的enum Orientation来声明两个枚举变量
Orientation ori_1, ori_2;
合并后:
typedef enum Orientation: NSUInteger {
Orientation_Portrait,
Orientation_Down,
Orientation_left,
Orientation_Right
} Orientation;
三. 基本使用方法
//定义枚举
typedef enum Orientation: NSUInteger {
Orientation_Portrait,
Orientation_Down,
Orientation_left,
Orientation_Right
} Orientation;
//创建枚举变量并赋值
Orientation QQ_Orientation = Orientation_Portrait;
//调用函数
[self defineQQOrientation:QQ_Orientation];
- (void)defineQQOrientation:(Orientation)orientation{
switch (orientation) {
case Orientation_Portrait:
break;
case Orientation_Down:
break;
case Orientation_left:
break;
case Orientation_Right:
break;
default:
break;
}
}
枚举的另一种使用方式是定义为按位掩码,当定义选项的时候,若这些选项可以彼此组合,则在设置特定的枚举值后,各选项间就可通过“按位或”来组合。因为每个枚举值所对应的二进制表示中,只有1个二进制位的值是1,所以多个选项“按位或”后的组合值是唯一的,且将某一选项与组合值做“按位与”操作,即可判断出组合值中是否包含该选项。
enum Orientation {
Orientation_Portrait = 1 << 0, // 0001
Orientation_Down = 1 << 1,// 0010
Orientation_left = 1 << 2,// 0100
Orientation_Right = 1 << 3// 1000
};
多选项使用方法:
typedef enum OrientationGroup {
OrientationGroup_Portrait = 1 << 0, // 0001,
OrientationGroup_Down = 1 << 1, // 0010,
OrientationGroup_left = 1 << 2, // 0100,
OrientationGroup_Right = 1 << 3, // 1000
} OrientationGroup;
//用“或”运算同时赋值多个选项
OrientationGroup orientationGroup = OrientationGroup_left | OrientationGroup_Down;
//用“与”运算取出对应位
if (orientationGroup & OrientationGroup_Portrait) {
NSLog(@"OrientationGroup_Portrait OK");
}
if (orientationGroup & OrientationGroup_left) {
NSLog(@"OrientationGroup_left OK");
}
if (orientationGroup & OrientationGroup_Right) {
NSLog(@"OrientationGroup_Right OK");
}
if (orientationGroup & OrientationGroup_Down) {
NSLog(@"OrientationGroup_Down OK");
}
运行结果:
2019-09-19 14:17:52.610619+0800 Text[2143:121039] OrientationGroup_left OK
2019-09-19 14:17:52.610763+0800 Text[2143:121039] OrientationGroup_Down OK
四. enum在Objective-C中的“升级版”
从C++ 11开始,我们可以为枚举指定其实际的存储类型,在枚举的定义中已经提到过,如下
//指明枚举类型保存变量的类型
enum Orientation: NSUInteger {
Orientation_Portrait,
Orientation_Down,
Orientation_left,
Orientation_Right
};
在Objective-C中为了保证枚举类型的兼容性,推荐使用NS_ENUM和NS_OPTIONS
// NS_ENUM,定义状态等普通枚举类型
typedef NS_ENUM(NSInteger, NS_Orientation) {
NS_Orientation_Portrait,
NS_Orientation_Down,
NS_Orientation_left,
NS_Orientation_Right
};
// NS_OPTIONS,定义可组合选项的枚举类型
typedef NS_OPTIONS(NSInteger, OP_Orientation) {
OP_Orientation_None = 0,
OP_Orientation_Portrait = 1 << 0,
OP_Orientation_Down = 1 << 1,
OP_Orientation_left = 1 << 2,
OP_Orientation_Right = 1 << 3
};