2
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

これまでのところ、私は理解しています。

しかし、メソッドはどの向きが有効かをどのようにチェックしていますか?

単純な列挙型の場合、 is が 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
}

その通りですか?

ありがとう

4

2 に答える 2

4

//...

実際には、0011 を返しています。

なんで?

非常に賢いアップルのエンジニアが、彼の enum にビット シフトされた値を割り当てることにしたためです。理由を本当に知りたい場合は、列挙型がビットフィールドであるためです。これは、おそらくメソッドにあらゆる種類の「オプション」をテストまたは適用する最も簡単な方法の1つです。

しかし、メソッドはどの向きが有効かをどのようにチェックしていますか?

単純な列挙がある場合、 is が 0、1、2、または 3 に等しいかどうかをチェックしているため...

しかし、コードは UIInterfaceOrientationMask をどのように扱っているのでしょうか? バイナリ AND で?

右端のビットが 2 進数で設定されているかどうかをテストする必要がある場合は0011、 をテストします(3 & 1)。これは true です (基本的には であるため(1 & 1))。したがって、列挙型は名前付きの整数にすぎないため (おそらく既にご存じのとおり)、完全に OR されたマスクを、関心のある 1 つ以上の特定の値に対して AND でテストし、関連するビットがマスクに存在するかどうかを確認します。 .

その特定の例では、さらに一歩進んでいます。オプション マスク内のビットの存在だけでなく、オプション全体をテストすることで、オプションのすべてのビットがそこにあることが保証されるため、「より安全な」テストが得られます。より複雑なビット マスクの場合、これはより理にかなっていますが、 のような単純なものの場合UIInterfaceOrientationMask、単純な ANDing が機能します。

于 2013-07-04T17:45:46.253 に答える