OC中NS_OPTIONS的使用
OC 常用的枚举有两种类型,分别是 NS_ENUM 和 NS_OPTIONS ,
普通使用推荐枚举NS_ENUM 方式,
需要安位或操作组合的方式就使用枚举NS_OPTIONS ,还有个功能就是可以多选
- 创建位移枚举
typedef NS_ENUM(NSUInteger, YLEnum) {
YLEnumTop = 1, // 0000 0001
YLEnumBottom , // 0000 0010
YLEnumLeft , // 0000 0011
YLEnumRight , // 0000 0100
};
- 位移枚举的使用
再创一个简单的位移枚举,表示着 上、下、左、右 四个方向
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: 中可以什么都不用做了)
- 方法调用和解析
[self optionsDemo: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 | 1 = 1
1 | 0 = 1
0 | 0 = 0
总结规则: 有1则为1 即:一真则真
解析的时候:按位 与 ‘&’ 运算 :
1 & 1 = 1
1 & 0 = 0
0 & 0 = 0
总结规则:有0则为0 即:一假则假
Swift Optionsets
对于位掩码,Swift 给出的方案是:选项集合(option sets)。在 C 和 Objective-C 中,通常的做法是将一个布尔值选项集合表示为一系列值为 2 的整数次幂的枚举成员。之后就可以使用位掩码来选择想要的选项了
使用结构体(struct
)来遵从 OptionSet
协议,以引入选项集合,而非枚举(enum
)。为什么这样处理呢?当枚举成员互斥的时候,比如说,一次只有一个选项可以被选择的情况下,枚举是非常好的。但是和 C 不同,在 Swift 中,你无法把多个枚举成员组合成一个值,而 C 中的枚举对编译器来说就是整型,可以接受任意整数值。
和 C 中一样,Swift 中的选项集合结构体使用了高效的位域来表示,但是这个结构体本身表现为一个集合,它的成员则为被选择的选项。这允许你使用标准的集合运算来维护位域,比如使用 contains 来检验集合中是否有某个成员,或者是用 union 来组合两个位域
struct CollecLayoutType : OptionSet {
let rawValue: UInt
static let CollecLayoutType_1 = CollecLayoutType(rawValue: 1 << 0)
static let CollecLayoutType_2 = CollecLayoutType(rawValue: 1 << 1)
static let CollecLayoutType_3 = CollecLayoutType(rawValue: 1 << 2)
static let CollecLayoutType_HNews = CollecLayoutType(rawValue: 1 << 3)
static let CollecLayoutType_BaseCell =
[CollecLayoutType_1, CollecLayoutType_2, CollecLayoutType_3]
}
使用:
let options: CollecLayoutType = [.CollecLayoutType_1, .CollecLayoutType_2] // 3 (= 1 + 2)
let op1 = options.contains(.CollecLayoutType_1) // → true
let op2 = options.contains(.CollecLayoutType_HNews) // → false
let op3 = options.union([.CollecLayoutType_3]) // → 7 (= 1 + 2 + 4)
let type: CollecLayoutType = .CollecLayoutType_1
if (type == .CollecLayoutType_1) { // → true
// TODO
}
if (CollecLayoutType.CollecLayoutType_BaseCell.contains(type)) { // → true
// TODO
}
网友评论