枚举值定义选项通过按位或来实现多选

  • 使用背景

苹果官方使用的情况

  1. 通知中心中的option选项
NSKeyValueObservingOptionNew = 0x01,
NSKeyValueObservingOptionOld = 0x02,
NSKeyValueObservingOptionInitial NS_ENUM_AVAILABLE(10_5, 2_0) = 0x04,
NSKeyValueObservingOptionPrior NS_ENUM_AVAILABLE(10_5, 2_0) = 0x08
  1. UIView中调整大小的一个枚举值
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
};

调用时

[[NSNotificationCenter defaultCenter] addObserver:self forKeyPath:self.textField.text options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil]; 

说明

options:NSKeyValueObservingOptionNew| NSKeyValueObservingOptionOld 

表示New选项和Old选项都被选中,即新值和旧值的选项都会触发.

  • 自定义使用方法

 typedef NS_OPTIONS(int, GCSelection){
    GCSelectionA = 1 << 0,
    GCSelectionB = 1 << 1,
    GCSelectionC = 1 << 2,
};

@interface ViewController ()
@property (nonatomic,assign) GCSelection selection;
@end

@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    [self printMyEnum:GCSelectionA | GCSelectionB];
}
- (void)printMyEnum:(GCSelection)selection {
    if (selection & GCSelectionA) {
        NSLog(@"A");
    }
    if (selection & GCSelectionB) {
        NSLog(@"B");
    }
    if (selection & GCSelectionC) {
        NSLog(@"C");
    }
}  

输出结果

输出结果.png
  • 使用分析

其实原理很简单,就是将枚举值转换成2进制数.下列每个枚举值的二进制数都有且仅有一位为1,如果我们使用按位或操作符去进行选择,那么就会达到多选的效果.

  • 分析原理
十六进制 --> 二进制
0x01  --> 0001
0x02  --> 0010
0x04  --> 0100
0x08  --> 1000
使用左移符号 <<
1的二进制形式是 --> 0001
1<<0 左移0位 --> 0001
1<<1 左移1位 --> 0010
1<<2 左移2位 --> 0100
1<<3 左移3位 --> 1000

在我们使用按位或操作符选择了多个选项的时候,系统会先进行按位或,得出结果:

比如demo中的:[self printMyEnum:GCSelectionA | GCSelectionB];
按位或的计算过程是:
0001
0010
---->
0011

现在我们选择的枚举值经过按位或操作后,有两位是1,即0011.这也就意味着我们进行了多选.所以在筛选枚举值的时候,我们用按位与就能准确得到选了哪些枚举值.

selection & GCSelectionA的计算过程是:

按位与
0011
0001
---->
0001

结果非0即真所以会打印A;

同理selection & GCSelectionB的计算过程是:

按位与
0011
0010
---->
0010

所以B也会打印.

你可能感兴趣的:(枚举值定义选项通过按位或来实现多选)