Obj-C中的多值枚举

gca*_*amp 48 iphone cocoa enums cocoa-touch objective-c

在Cocoa和Cocoa Touch框架中,枚举用作常量.我理解如何使用它,除了在一种情况下,您可以作为参数多个值传递给|操作符.像 :

pageControl.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin);
Run Code Online (Sandbox Code Playgroud)

枚举声明如下:

enum {
    UIViewAutoresizingNone                 = 0,
    UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,
    UIViewAutoresizingFlexibleWidth        = 1 << 1,
    UIViewAutoresizingFlexibleRightMargin  = 1 << 2,
    UIViewAutoresizingFlexibleTopMargin    = 1 << 3,
    UIViewAutoresizingFlexibleHeight       = 1 << 4,
    UIViewAutoresizingFlexibleBottomMargin = 1 << 5
};
typedef NSUInteger UIViewAutoresizing;
Run Code Online (Sandbox Code Playgroud)

如何定义自己这种类型的枚举(即什么<<意思)以及如何在作为参数传递时检查倍数值?

Joe*_*oel 114

<<是bitshift运算符.所以1 << 2告诉它将两个空格移位.

例:

在二进制中,数字1是:

0001
Run Code Online (Sandbox Code Playgroud)

1 << 2 意味着将所有位移到左侧2个空格,这会产生以下值:

0100
Run Code Online (Sandbox Code Playgroud)

4.

因此,示例中每个ENUM的值为1,2,4,8,16等.它们也可以将每个枚举设置为这些值.但由于它们将该枚举用于多个值,因此二进制值使其更清晰:

0001
0010
0100
1000
Run Code Online (Sandbox Code Playgroud)

所以他们用位移写了.

所以,如果我|将这两个值中的两个值合并在一起,例如FlexibleLeftMargin(0001)和FlexibleWidth(0010),我会得到以下值:

0011
Run Code Online (Sandbox Code Playgroud)

因此,他们将每个位用作标志,以便他们知道您设置了多个值.

您现在可以使用AND运算符&来确定您是否设置了特定值.

0010 & 0011 = 0010
Run Code Online (Sandbox Code Playgroud)

所以你可以这样做来检查你是否设置了一个枚举:

myenum = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin);
if((myenum & UIViewAutoresizingFlexibleLeftMargin) == UIViewAutoresizingFlexibleLeftMargin) {
  // myenum has UIViewAutoresizingFlexibleLeftMargin set!
}
Run Code Online (Sandbox Code Playgroud)

希望这是有道理的.有关按位运算的更详尽解释请阅读:维基百科〜位运算符或搜索" 位运算符 "

  • 这里要小心,因为你的例子不起作用.Equality(==)的优先级高于bitwise和(&)的C,所以除非(myenum&0x01)为真,否则总是会失败,我认为这不是你的意思.需要是if((myenum&UIViewAutoresizingFlexibleLeftMargin)== UIViewAutoresizingFlexibleLeftMarging)doSoemthing() (4认同)