美文网首页杂文小品
iOS中NS_OPTIONS 位移枚举详解

iOS中NS_OPTIONS 位移枚举详解

作者: MiniCoder | 来源:发表于2020-03-14 18:25 被阅读0次

    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
    }
    

    相关文章

      网友评论

        本文标题:iOS中NS_OPTIONS 位移枚举详解

        本文链接:https://www.haomeiwen.com/subject/iingshtx.html