OC中NS_OPTIONS的使用
OC 常用的枚舉有兩種類型,分別是 NS_ENUM 和 NS_OPTIONS ,
普通使用推薦枚舉NS_ENUM 方式,
需要安位或操作組合的方式就使用枚舉NS_OPTIONS ,還有個功能就是可以多選
- 創(chuàng)建位移枚舉
typedef NS_ENUM(NSUInteger, YLEnum) {
YLEnumTop = 1, // 0000 0001
YLEnumBottom , // 0000 0010
YLEnumLeft , // 0000 0011
YLEnumRight , // 0000 0100
};
- 位移枚舉的使用
再創(chuàng)一個簡單的位移枚舉,表示著 上、下、左、右 四個方向
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做參數(shù),這時效率最高(因為在方法 optionsDemo: 中可以什么都不用做了)
- 方法調(diào)用和解析
[self optionsDemo:YLOptionsTop | YLOptionsRight];
//多選時,用加法來進行枚舉的疊加,減法來進行枚舉的刪除
//根據(jù)打印可以知道 type == 9
// type 是 top 和 right 相加得來的
// 0000 0001 + 0000 1000 = 0000 1001 即為 9
- (void)optionsDemo:(YLOptions)type{
//根據(jù)下面的 按位運算 就可以計算出結(jié)果了
//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);
}
}
- 位移枚舉的運算:位移枚舉采用二進制的運算規(guī)則
調(diào)用方法傳值時使用‘|’運算:按位 或 | 運算:
1 | 1 = 1
1 | 0 = 1
0 | 0 = 0
總結(jié)規(guī)則: 有1則為1 即:一真則真
解析的時候:按位 與 ‘&’ 運算 :
1 & 1 = 1
1 & 0 = 0
0 & 0 = 0
總結(jié)規(guī)則:有0則為0 即:一假則假
Swift Optionsets
對于位掩碼,Swift 給出的方案是:選項集合(option sets)。在 C 和 Objective-C 中,通常的做法是將一個布爾值選項集合表示為一系列值為 2 的整數(shù)次冪的枚舉成員。之后就可以使用位掩碼來選擇想要的選項了
使用結(jié)構(gòu)體(struct)來遵從 OptionSet 協(xié)議,以引入選項集合,而非枚舉(enum)。為什么這樣處理呢?當枚舉成員互斥的時候,比如說,一次只有一個選項可以被選擇的情況下,枚舉是非常好的。但是和 C 不同,在 Swift 中,你無法把多個枚舉成員組合成一個值,而 C 中的枚舉對編譯器來說就是整型,可以接受任意整數(shù)值。
和 C 中一樣,Swift 中的選項集合結(jié)構(gòu)體使用了高效的位域來表示,但是這個結(jié)構(gòu)體本身表現(xiàn)為一個集合,它的成員則為被選擇的選項。這允許你使用標準的集合運算來維護位域,比如使用 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
}