一、场景
当我们使用枚举这个东西时,有时需要多个枚举值任一一个满足时就ture,但是常用的枚举NS_ENUM定义好的枚举只能挨个判断,写一坨就既不美观也不好阅读,如下:
c
typedef NS_ENUM (NSInteger, RPTestType){
RPTestTypeUnknown = 0, // unknow
RPTestTypeValue0, // 值0
RPTestTypeValue1, // 值1
RPTestTypeValue2, // 值2
RPTestTypeValue3, // 值3
RPTestTypeValue4, // 值4
RPTestTypeValue5, // 值5
};
RPTestType testTeype = RPTestTypeUnknown;
if (testTeype == RPTestTypeValue0 ||
testTeype == RPTestTypeValue1 ||
testTeype == RPTestTypeValue2 ||
testTeype == RPTestTypeValue3 ||
testTeype == RPTestTypeValue4 ||
testTeype == RPTestTypeValue5) {
NSLog(@"ture");
}
二、利用NS_OPTIONS优化
1、先了解一个关于位运算符的知识点:位运算符浅析
这里用到(右移 << )和 (按位与 & )和(按位或 | )这仨,先明确是怎么个事;
2、先看下NS_OPTIONS如何来定义枚举
c
typedef NS_OPTIONS (NSInteger, RPTestType){
RPTestTypeUnknown = 1 << 0, // unknow
RPTestTypeValue0 = 1 << 1, // 值0
RPTestTypeValue1 = 1 << 2, // 值1
RPTestTypeValue2 = 1 << 3, // 值2
RPTestTypeValue3 = 1 << 4, // 值3
RPTestTypeValue4 = 1 << 5, // 值4
RPTestTypeValue5 = 1 << 6, // 值5
};
这里使用右移定义枚举值,结合位运算可以这么看:
1 << 0 就是 0001,即2的0次方;
1 << 1 就是 0010,即2的1次方;
1 << 2 就是 0100,即2的2次方;
以此类推~
3、再看这么用的好处
当有多个枚举值都符合时做判断时候,可以直接(或 | )起来,然后(与 & )一下子,就能清晰明了的做判断;
c
RPTestType testType = RPTestTypeUnknown;
RPTestType judgeType = RPTestTypeValue0 | RPTestTypeValue1 | RPTestTypeValue2 | RPTestTypeValue3 | RPTestTypeValue4 | RPTestTypeValue5;
if (testType & judgeType) {
NSLog(@"ture");
}
当然最好使的用处是枚举值传参,如SDImage
c
[self.testImgView sd_setImageWithURL:[NSURL URLWithString:@"xx"]
placeholderImage:nil
options:SDWebImageLowPriority |
SDWebImageProgressiveLoad |
SDWebImageRefreshCached |
SDWebImageContinueInBackground];
options这里可以直接传入多个枚举值,可用于方法内部与或运算进行判断,方便传值;类似的还有UIControlState;
c
typedef NS_OPTIONS(NSUInteger, UIControlState) {
UIControlStateNormal = 0,
UIControlStateHighlighted = 1 << 0, // used when UIControl isHighlighted is set
UIControlStateDisabled = 1 << 1,
UIControlStateSelected = 1 << 2, // flag usable by app (see below)
UIControlStateFocused API_AVAILABLE(ios(9.0)) = 1 << 3, // Applicable only when the screen supports focus
UIControlStateApplication = 0x00FF0000, // additional flags available for application use
UIControlStateReserved = 0xFF000000 // flags reserved for internal framework use
};
c
[testBtn setTitle:@"xx"
forState:UIControlStateNormal |
UIControlStateHighlighted |
UIControlStateSelected];