苹果API中经常看到位运算示例,如下

self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {
    UIViewAutoresizingNone                 = 0,
    UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,
    UIViewAutoresizingFlexibleWidth        = 1 << 1,
    UIViewAutoresizingFlexibleRightMargin  = 1 << 2,
    UIViewAutoresizingFlexibleTopMargin    = 1 << 3,
    UIViewAutoresizingFlexibleHeight       = 1 << 4,
    UIViewAutoresizingFlexibleBottomMargin = 1 << 5
};

那么原理是什么呢?

按位与(&)运算:两个都是是1才是1,否则为0

& 语法:两个都是是1才是1,否则为0
 0b 0100
&0b 1110
---------
 0b 0110

### 按位或(|)运算:两个都是是1才是1,否则为0

 0b 0100
|0b 1110
---------
 0b 1110

自己动手模拟设计一个枚举,使用按位或可以传多个参数

首先枚举设计,必须是特定值必须是2的倍数

typedef enum {
    // 根据实际情况是否需要none
    DXOptionsNone = 0,
    DXOptionsOne = 1,   // 2^0
    DXOptionsTwo = 2,   // 2^1
    DXOptionsThree = 4, // 2^2
    DXOptionsFour = 8   // 2^3
} DXOptions;

等价于

typedef enum {
    DXOptionsNone = 0,     // 0b 0000 0000
    DXOptionsOne = 1<<0,   // 0b 0000 0001
    DXOptionsTwo = 1<<1,   // 0b 0000 0010
    DXOptionsThree = 1<<2, // 0b 0000 0100
    DXOptionsFour = 1<<3   // 0b 0000 1000
} DXOptions;

设计一个方法,接受参数,传过来的参数通过按位与&相应的值,就能判断是否包含这个枚举

- (void)setOptions:(DXOptions)options{
    if (options & DXOptionsNone) {
        // 0000 0000 & 任何值都是0 因此这句代码永远不会执行
        NSLog(@"包含了DXOptionsNone");
    }
    if (options & DXOptionsOne) {
        NSLog(@"包含了DXOptionsOne");
    }
    if (options & DXOptionsTwo) {
        NSLog(@"包含了DXOptionsTwo");
    }
    if (options & DXOptionsThree) {
        NSLog(@"包含了DXOptionsThree");
    }
    if (options & DXOptionsFour) {
        NSLog(@"包含了DXOptionsFour");
    }
}

测试

[self setOptions:DXOptionsFour | DXOptionsOne];

关于第一个枚举None的判断,可以加一个数组作为判断,代码如下

- (void)setOptions:(DXOptions)options{
    NSMutableArray *array = [NSMutableArray array];
    if (options & DXOptionsNone) {
        // 0000 0000 & 任何值都是0 因此这句代码永远不会执行
        NSLog(@"包含了DXOptionsNone");
    }
    if (options & DXOptionsOne) {
        NSLog(@"包含了DXOptionsOne");
        NSNumber *num = [NSNumber numberWithInt:DXOptionsOne];
        [array addObject:num];
    }
    if (options & DXOptionsTwo) {
        NSLog(@"包含了DXOptionsTwo");
        NSNumber *num = [NSNumber numberWithInt:DXOptionsTwo];
        [array addObject:num];
    }
    if (options & DXOptionsThree) {
        NSLog(@"包含了DXOptionsThree");
        NSNumber *num = [NSNumber numberWithInt:DXOptionsThree];
        [array addObject:num];
    }
    if (options & DXOptionsFour) {
        NSLog(@"包含了DXOptionsFour");
        NSNumber *num = [NSNumber numberWithInt:DXOptionsFour];
        [array addObject:num];
    }
    
    if (array.count == 0) {
        NSLog(@"包含了DXOptionsNone");
    }
}