通过UIInterfaceOrientationMask了解Objective-C / iOS的C ++枚举

时间:2013-07-04 17:13:38

标签: c++ ios objective-c enums bit-shift

UIInterfaceOrientationMask is defined as:

typedef enum {
   UIInterfaceOrientationMaskPortrait = (1 << UIInterfaceOrientationPortrait),
   UIInterfaceOrientationMaskLandscapeLeft = (1 << UIInterfaceOrientationLandscapeLeft),
   UIInterfaceOrientationMaskLandscapeRight = (1 << UIInterfaceOrientationLandscapeRight),
   UIInterfaceOrientationMaskPortraitUpsideDown = (1 << UIInterfaceOrientationPortraitUpsideDown),
   UIInterfaceOrientationMaskLandscape =
   (UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight),
   UIInterfaceOrientationMaskAll =
   (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft |
   UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskPortraitUpsideDown),
   UIInterfaceOrientationMaskAllButUpsideDown =
   (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft |
   UIInterfaceOrientationMaskLandscapeRight),
} UIInterfaceOrientationMask;

轻松完成工作,简化枚举:

typedef enum {
   UIInterfaceOrientationMaskPortrait = (1 << 0),
   UIInterfaceOrientationMaskLandscapeLeft = (1 << 1),
   UIInterfaceOrientationMaskLandscapeRight = (1 << 2),
   UIInterfaceOrientationMaskPortraitUpsideDown = (1 << 3)
} UIInterfaceOrientationMask;

这意味着:

typedef enum {
   UIInterfaceOrientationMaskPortrait = 0001,
   UIInterfaceOrientationMaskLandscapeLeft = 0010,
   UIInterfaceOrientationMaskLandscapeRight = 0100,
   UIInterfaceOrientationMaskPortraitUpsideDown = 1000
} UIInterfaceOrientationMask;

这是可能的,因为这个枚举使用C位移位: http://en.wikipedia.org/wiki/Bitwise_operation#Bit_shifts

然后我们写:

- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait | UInterfaceOrientationMaskLandscapeLeft;
}

事实上我们正在回归:0011

为什么呢?因为二进制OR

0001或0010 = 0011

0 OR 0 = 0
0 OR 1 = 1
1 OR 0 = 1
1 OR 1 = 1

到目前为止,我理解。

但是,该方法如何检查哪个方向有效?

因为如果我们有一个简单的枚举,我们检查是否等于0,1,2或3

typedef enum {
   simpleZero,
   simpleOne ,
   simpleTwo ,
   simpleThree 
} simple;

int whatever = someNumber

if (whatever == simpleZero)
{
}
else if  (whatever == simpleOne)
{
}
.......

但是,代码如何处理UIInterfaceOrientationMask?使用二进制AND?

if (returnFromSupportedInterfaceOrientations & UIInterfaceOrientationMaskPortrait ==     UIInterfaceOrientationMaskPortrait)
{
// Do something
// Here is TRUE  0011 AND 0001 = 0001
}


if (returnFromSupportedInterfaceOrientations & UIInterfaceOrientationMaskLandscapeLeft == UIInterfaceOrientationMaskLandscapeLeft)
{
// Do something
// Here is TRUE  0011 AND 0010 = 0010
}

if (returnFromSupportedInterfaceOrientations & UIInterfaceOrientationMaskLandscapeLeft == UIInterfaceOrientationMaskLandscapeLeft)
{
// Do something
// Here is FALSE  0011 AND 0100 = 0000
}

那是这样吗?

由于

2 个答案:

答案 0 :(得分:4)

  

// ...

     

事实上我们正在回归:0011

     

为什么?

因为一个非常聪明的苹果工程师决定分配他的枚举位移位值。如果你真的想知道原因,那是因为枚举是bitfields,这可能是测试或应用任何类型“选项”到方法的最快方法之一。

  

但是,该方法如何检查哪个方向有效?

     

因为如果我们有一个简单的枚举,我们正在检查是否等于   0,1,2或3   ...

     

但是,代码如何处理UIInterfaceOrientationMask?使用二进制AND?

如果您需要测试最右边的位是否设置为二进制数0011,则测试(3 & 1),这是真的(因为它基本上是(1 & 1))。因此,因为枚举只是命名整数(正如您可能已经知道的那样),所以您可以通过ANDing测试完整的OR一起掩码与您感兴趣的任何一个或多个特定值,以检查掩码中是否存在相关位

在该具体示例中,它更进了一步。通过不仅测试选项掩码中位的存在,而且测试整个选项,您可以获得“更安全”的测试,因为它可以保证 all 选项的位都在那里。对于更复杂的位掩码,这更有意义,但对于像UIInterfaceOrientationMask这样的简单掩码,简单的AND运行。

答案 1 :(得分:1)

您的建议绝对有效:使用“按位与”运算符,然后检查结果为零(目标位未设置)。

作为一个机器背后,你可以想象枚举像一堆彩色pensils。它们可以是连续的“红橙黄绿色......”作为彩虹,从那时起就没有限制提供像“橙蓝紫”这样的精确颜色。

因此,您可以选择分配给每个枚举成员的值(如果您不提供一个,编译器将根据自己的意愿分配下一个可用值),请确定您是否需要顺序或自定义顺序值等