iOS中NS_OPTIONS 位移枚舉詳解

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
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容