复选枚举(位移枚举)的实现逻辑
2016-11-23 本文已影响60人
Mark_Guan
下面我们先来看看我们在开发中经常使用的苹果为我们提供的两个枚举值:
NS_ENUM
typedef NS_ENUM(NSInteger, UIButtonType) {
UIButtonTypeCustom = 0, // no button type
UIButtonTypeSystem NS_ENUM_AVAILABLE_IOS(7_0), // standard system button
UIButtonTypeDetailDisclosure,
UIButtonTypeInfoLight,
UIButtonTypeInfoDark,
UIButtonTypeContactAdd,
UIButtonTypePlain API_AVAILABLE(tvos(11.0)) API_UNAVAILABLE(ios, watchos), // standard system button without the blurred background view
UIButtonTypeRoundedRect = UIButtonTypeSystem // Deprecated, use UIButtonTypeSystem instead
};
该类型的枚举我们只能传递一个值,不能组合使用,比如:
UIButton *loginBtn = [UIButton buttonWithType:UIButtonTypeCustom];
关于这种枚举没有什么多说的,今天我们重点讨论的是下面的这种枚举以及实现方式
NS_OPTIONS
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
};
这种枚举与上面的不同,在使用的时候我们可以组合使用,传递多个值 比如:
self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleTopMargin;
那么不知道读者有没有想过这样一个问题,我们传递了多个数据,那么程序内部是如何去判断我们分别传递了那些值呢?
再具体的分析之前我们先来回忆一下 位运算的相关知识
|
如果两个相应的二进制位只要有一个是1,结果就是1;否则为0。
比如
00000001
| 00000010
____________
00000011
&
如果两个相应的二进制位都为1,则该位的结果值为1;否则为0。
比如
00000011 00000011 00000011
& 00000001 & 00000010 &上一个之前不包含的数据=> & 00000100
____________ ______________ ______________
00000001 00000010 00000000
通过上面的运算我们可以看到 通过 &
运算之后可以得到它本身.
也就是如果e = a| b | c | d,那么e & a 、e & b 、e & c 、 e & d都为true.
就是说你这个枚举值包含了那些原始枚举值,&操作值都为true.否则为false
<<
向左移一位,右边自动补0
比如 1 << 1 = 2
00000001 << 1
00000010 = 2
所以通过上面的分析我们不难猜出位移枚举的内部判断逻辑应该是这样的:
- (void)setOptions:(UIViewAutoresizing)options
{
if (options & UIViewAutoresizingFlexibleWidth) {
NSLog(@"包含了UIViewAutoresizingFlexibleWidth");
}
if (options & UIViewAutoresizingFlexibleHeight) {
NSLog(@"包含了UIViewAutoresizingFlexibleWidth");
}
if (options & UIViewAutoresizingFlexibleTopMargin) {
NSLog(@"包含了UIViewAutoresizingFlexibleWidth");
}
}