zoukankan      html  css  js  c++  java
  • 位移枚举

    了解位移枚举之前,我们先回顾一下C语言位运算符。

    1     << : 左移,比如1<<n,表示1往左移n位,即数值大小2的n次方; 例如 : 0b0001 << 1 变为了 0b0010 
    2     >> : 右移,类似左移,数值大小除以2的n次方
    3     &  : 按位与,1与任意数等于任意数本身,0与任意数等于0,即1&x=x,0&x=0
    4     |  : 按位或,x|y中只要有一个1则结果为1;反之为0
    5     ^  : 按位异或,x^y相等则为0,不等则为1

    开发中,你也许见到过或用过类似这种的枚举类型:

    typedef NS_OPTIONS(NSUInteger, BDRequestOptions) {
        BDRequestOptionSuccess     = 1 << 0, // 1
        BDRequestOptionFailure     = 1 << 1, // 2
        BDRequestOptionProcessing  = 1 << 2, // 4
        BDRequestOptionAnimate     = 1 << 3, // 8
    };

    这种枚举类型,称之为按位掩码(bitmask),他的语法和枚举相同。

    从枚举定义来看,NS_ENUM和NS_OPTIONS本质是一样的,而iOS使用两种方式定义的目的是区分使用场景 : 是否可以多选

    NS_OPTION枚举 :  多个枚举值同时使用按位或( | )相加表示进行多选操作。位移不同位数得到值不同即数值代表的枚举值不同,多个枚举同时使用仍具有唯一性。

    NS_ENUM枚举   :  不可多选,唯一互斥性。

    示例:

    // 首先定义一组
    typedef NS_OPTIONS(NSUInteger, BDRequestOptions) {
        BDRequestOptionSuccess     = 1 << 0,
        BDRequestOptionFailure     = 1 << 1,
        BDRequestOptionProcessing  = 1 << 2,
        BDRequestOptionAnimate     = 1 << 3,
    };
    
    // 然后调用我们定义的方法
    #pragma mark - View lifeCycle
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.view.backgroundColor = [UIColor orangeColor];
        
        [self test:BDRequestOptionSuccess | BDRequestOptionFailure | BDRequestOptionProcessing | BDRequestOptionAnimate];
    }
    
    - (void)test:(BDRequestOptions)type {
        if (type & BDRequestOptionSuccess) {
            NSLog(@"BDRequestOptionSuccess");
        }
        if (type & BDRequestOptionFailure) {
            NSLog(@"BDRequestOptionFailure");
        }
        if (type & BDRequestOptionProcessing) {
            NSLog(@"BDRequestOptionProcessing");
        }
        if (type & BDRequestOptionAnimate) {
            NSLog(@"BDRequestOptionAnimate");
        }
    }
    
    // 查看打印结果:
    2016-04-04 14:09:44.946 OC测试[5869:719056] BDRequestOptionSuccess
    2016-04-04 14:09:44.947 OC测试[5869:719056] BDRequestOptionFailure
    2016-04-04 14:09:44.947 OC测试[5869:719056] BDRequestOptionProcessing
    2016-04-04 14:09:44.947 OC测试[5869:719056] BDRequestOptionAnimate

    分析:

    // 首先定义一组
    typedef NS_OPTIONS(NSUInteger, BDRequestOptions) {
        BDRequestOptionSuccess     = 0b0001 << 0,
        BDRequestOptionFailure     = 0b0010 << 1,
        BDRequestOptionProcessing  = 0b0100 << 2,
        BDRequestOptionAnimate     = 0b1000 << 3,
    };
    
    #pragma mark - View lifeCycle
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.view.backgroundColor = [UIColor orangeColor];
        
        [self test:BDRequestOptionSuccess | BDRequestOptionFailure | BDRequestOptionProcessing | BDRequestOptionAnimate];
        /** 
         BDRequestOptionSuccess | BDRequestOptionFailure | BDRequestOptionProcessing | BDRequestOptionAnimate
         
         等同于:0b0001 |
               0b0010 |
               0b0100 |
               0b1000 
         结果为:0b1111
         */
    }
    
    - (void)test:(BDRequestOptions)type {
        // 0b1111 & 0b0001 --->  0b0b0001
        if (type & BDRequestOptionSuccess) {
            NSLog(@"BDRequestOptionSuccess");
        }
        // 0b1111 & 0b0010 --->  0b0b0010
        if (type & BDRequestOptionFailure) {
            NSLog(@"BDRequestOptionFailure");
        }
        // 0b1111 & 0b0100 --->  0b0b0100
        if (type & BDRequestOptionProcessing) {
            NSLog(@"BDRequestOptionProcessing");
        }
        // 0b1111 & 0b1000 --->  0b0b1000
        if (type & BDRequestOptionAnimate) {
            NSLog(@"BDRequestOptionAnimate");
        }
    }

    另,默认的,如果开发中枚举值传0,意味着不做任何操作。

    例如:

    // 传0,不打印任何值
    [self test:0];

    具体用途:

    // 以下所说的 0 或 1,均指二进制数字中的 0 或 1
        // 1、赋值。
        self.requestOption = BDRequestOptionSuccess | BDRequestOptionFailure | BDRequestOptionProcessing | BDRequestOptionAnimate;
        
        // 2、判断是否包含。
        // &:按位与,1与任意数等于任意数本身,0与任意数等于0,即1&x=x,0&x=0
        if (self.requestOption & BDRequestOptionSuccess) {
            NSLog(@"已包含了该枚举值");
        } else {
            NSLog(@"不包含该枚举值");
        }
        
        // 3、累加。 累加已经累加过的枚举值, 虽然枚举变量的值不会有变动,但这样将会误导阅读代码的人。
        // |: 按位或,x|y中只要有一个1则结果为1;反之为0
        self.requestOption |= BDRequestOptionSuccess;
        
        // 4、累减。 如果累减不存在的枚举值, 那么本次累减的枚举值,会自动累加上去。
        // ^:按位异或,x^y相等则为0,不等则为1
        self.requestOption ^= BDRequestOptionSuccess;

    OC中的用法:

    NSString *string = @"Learning";
        [string boundingRectWithSize:CGSizeMake(CGRectGetWidth(self.view.frame), MAXFLOAT)
                             options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingTruncatesLastVisibleLine
                          attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:12.f]}
                             context:nil];

    上面传值:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingTruncatesLastVisibleLine

    逻辑处理:

     1     // 对传入的option逻辑处理
     2     if (option & NSStringDrawingUsesLineFragmentOrigin) {
     3         // 包含   NSStringDrawingUsesLineFragmentOrigin
     4     } else {
     5         // 未包含 NSStringDrawingUsesLineFragmentOrigin
     6     }
     7     if (option & NSStringDrawingTruncatesLastVisibleLine) {
     8         // 包含   NSStringDrawingTruncatesLastVisibleLine
     9     } else {
    10         // 未包含 NSStringDrawingTruncatesLastVisibleLine
    11     }

    对于位移枚举的具体使用方法,建议可以查看一些三方库,例如SDWebImage等!

    尊重作者劳动成果,转载请注明: 【kingdev】

  • 相关阅读:
    linux shell 总结
    python小结
    python与execl的读写
    利用burpsuits暴力破解登陆界面
    python之函数的使用
    Sublime text怎么识别input函数
    ping的禁止
    Hbase的配置与使用
    JAVA 利用反射自定义数据层框架
    JAVA实现网页上传头像
  • 原文地址:https://www.cnblogs.com/xiu619544553/p/5351999.html
Copyright © 2011-2022 走看看