iOS NS_OPTIONS 位移枚举
『前言』
枚举值是一个整形(int),并且它不参与内存的占用和释放,枚举定义变量即可直接使用,不用初始化.在代码中使用枚举的目的只有一个,那就是增加代码的可读性.
iOS 常用的枚举有两种类型,分别是 NS_ENUM
和 NS_OPTIONS
,
普通使用推荐枚举NS_ENUM
方式,
需要安位或操作组合的方式就使用枚举NS_OPTIONS
,还有个功能就是可以多选
1.创建位移枚举
先创建一个普通的枚举
typedef NS_ENUM(NSUInteger, YLEnum) {
YLEnumTop = 1, // 0000 0001
YLEnumBottom , // 0000 0010
YLEnumLeft , // 0000 0011
YLEnumRight , // 0000 0100
};
根据以往的开发经验可以知道 YLEnumTop
的枚举值是1
,YLEnumBottom
是2
, YLEnumLeft
是3
,YLEnumRight
是4
,后面的注释 是转化为二进制后的值
再创一个简单的位移枚举,表示着 上、下、左、右 四个方向
typedef NS_OPTIONS(NSUInteger, YLOptions) {
YLOptionsTop = 1 << 0, // 0000 0001
YLOptionsBottom = 1 << 1, // 0000 0010
YLOptionsLeft = 1 << 2, // 0000 0100
YLOptionsRight = 1 << 3, // 0000 1000
};
- 注释:
<<
表示向左移动;
表示 :1<<n
表示1向左移动n位,
计算公式 :1*2^n
1乘以2的n次方;
PS: 位移枚举 YLOptions 第一个枚举值是 YLOptionsTop , 如果该枚举值
!=0
,那么可以默认传0
做参数,这时效率最高(因为在方法optionsDemo:
中可以什么都不用做了)
<<
位移符移动方法
举个🌰:
YLOptionsLeft = 1 << 2, // 0000 0100
<<
符号前面的1
表示基础数值,即要在1
的基础上向左移动2
位
1
的二进制表示为 0000 0001
,
向左移动2
位后的结果就是 0000 0100
,这个时候YLOptionsLeft
的枚举值就变成了4
了
经过位移移动后YLOptions的枚举值就可以看成是
typedef NS_OPTIONS(NSUInteger, YLOptions) {
YLOptionsTop = 1, // 0000 0001
YLOptionsBottom = 2, // 0000 0010
YLOptionsLeft = 4, // 0000 0100
YLOptionsRight = 8, // 0000 1000
};
举个🌰:
YLOptionsLeft = 3 << 1,
3
的二进制是 0000 0011
,
移动1
位后是 0000 0110
,
YLOptionsLeft
的枚举值就成了 6
公式计算的话就是 3*2^1 = 6。
2.位移枚举的使用
普通枚举NS_ENUM
判断可以使用 if else
和 switch
位移枚举NS_OPTIONS
的判断方法如下:
- (void)optionsDemo:(YLOptions)type{
if (type & YLOptionsTop) {
NSLog(@"上 %ld",type & YLOptionsTop);
}
if (type & YLOptionsBottom) {
NSLog(@"下 %ld",type & YLOptionsBottom);
}
if (type & YLOptionsLeft) {
NSLog(@"左 %ld",type & YLOptionsLeft);
}
if (type & YLOptionsRight) {
NSLog(@"右 %ld",type & YLOptionsRight);
}
}
方法调用
[self optionsDemo:YLOptionsTop | YLOptionsRight];
会有两个打印输出
2018-08-21 13:39:34.750480+0800 Demo[20332:1760218] 上 1
2018-08-21 13:39:34.750586+0800 Demo[20332:1760218] 右 8
这样就实现了 多选
功能,多个枚举值 要使用 | 或
符号
解析方法的调用
方法调用
[self optionsDemo:YLOptionsTop | YLOptionsRight];
这时的type
是 YLOptionsTop | YLOptionsRight
多选时,用加法来进行枚举的叠加,减法来进行枚举的删除
//多选时,用加法来进行枚举的叠加,减法来进行枚举的删除
//根据打印可以知道 type == 9
// type 是 top 和 right 相加得来的
// 0000 0001 + 0000 1000 = 0000 1001 即为 9
- (void)optionsDemo:(YLOptions)type{
//根据下面的 按位运算 就可以计算出结果了
//1001 & 0001 0001
if (type & YLOptionsTop) {
NSLog(@"上 %ld",type & YLOptionsTop);
}
//1001 & 0010 0000
if (type & YLOptionsBottom) {
NSLog(@"下 %ld",type & YLOptionsBottom);
}
//1001 & 0100 0000
if (type & YLOptionsLeft) {
NSLog(@"左 %ld",type & YLOptionsLeft);
}
//1001 & 1000 1000
if (type & YLOptionsRight) {
NSLog(@"右 %ld",type & YLOptionsRight);
}
}
也可以这样理解
理解1:
//1001 & 1000 1000 转成十进制是 8 是>0的 那么 1001 & 1000 是真的,就会有打印输出
if (type & YLOptionsRight) {
NSLog(@"右 %ld",type & YLOptionsRight);
}
理解2:
(type & YLOptionsRight) 与 的 二进制值是 1000 对应的枚举值是 YLOptionsRight
这样写 会清晰一些
if ((type & YLOptionsRight) == YLOptionsRight) {
NSLog(@"右 %ld",type & YLOptionsRight);
}
3.按位运算
- 按位
与 &
运算 :
1 & 1 = 1
1 & 0 = 0
0 & 0 = 0
总结规则:有0则为0 即:一假则假
- 按位
或 |
运算:
1 | 1 = 1
1 | 0 = 1
0 | 0 = 0
总结规则: 有1则为1 即:一真则真
4.二进制的与 、或 运算
举个🌰:
0000 0010
和 0000 0100
相或 和 相与
二进制的与或运算,是每一位的对比运算,而不是总体所代表的值的对比运算
1.0000 0010
| 0000 0100
根据上面的按位运算, 前四位都是0 咱简单的只对比后四位
0010 | 按位运算符 | 0100 | 结果 | |
---|---|---|---|---|
第一位 | 0 | 或 | 0 | 0 |
第二位 | 0 | 或 | 1 | 1 |
第三位 | 1 | 或 | 0 | 1 |
第四位 | 0 | 或 | 0 | 0 |
结果就是 0110
这样就可以看出 之前说的 传参是YLOptionsTop | YLOptionsRight
,为什么type
的结果是9
了
2.0000 0010
& 0000 0100
0010 | 按位运算符 | 0100 | 结果 | |
---|---|---|---|---|
第一位 | 0 | 与 | 0 | 0 |
第二位 | 0 | 与 | 1 | 0 |
第三位 | 1 | 与 | 0 | 0 |
第四位 | 0 | 与 | 0 | 0 |
结果是 0000