这个“&”怎么样?在这份声明中工作?

时间:2010-04-18 13:03:20

标签: objective-c cocoa

我知道按位AND是如何工作的,但我不明白(sourceDragMask& NSDragOperationGeneric)是如何工作的,我不明白。有没有人可以向我解释?非常感谢。

- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
{
    NSPasteboard *pboard;
    NSDragOperation sourceDragMask;

    sourceDragMask = [sender draggingSourceOperationMask];
    pboard = [sender draggingPasteboard];

    if ( [[pboard types] containsObject:NSColorPboardType] )
    {
        if (sourceDragMask & NSDragOperationGeneric)
        {
            return NSDragOperationGeneric;
        }
    }

    return NSDragOperationNone;
}

3 个答案:

答案 0 :(得分:6)

NSDragOperationGeneric是一个位掩码 - 可能是2的幂 - 意味着数字中只有一位被设置。当且仅当&中设置了相应的位时,带有sourceDragMask的逐位sourceDragMask将产生非零输出。

假设(我不知道NSDragOperationGeneric的实际值):

sourceDragMask:         00011010
NSDragOperationGeneric: 00001000
a & b:                  00001000

简而言之,如果sourceDragMask设置了“NSDragOperationGeneric”位,则if语句将成功。

答案 1 :(得分:3)

sourceDragMask是所谓的位掩码:一个表示许多布尔标志的整数。它被声明为NSDragOperation类型的变量,实际上typedef来自NSUInteger - 它实际上就是这样。

首先,&运算符是所谓的“按位AND”,它只需要两个数字AND的每个位来创建一个新值。例如,0011 1001 & 0101 1010 == 0001 0001 - 57 & 90 = 17。同样,|运算符执行按位OR运算。使用这些运算符,我们可以分别使用这些1和0中的每一个作为布尔标志。

所以,例如,如果sourceDragMask是值12,那么这告诉我们什么?在二进制文件中,12表示为0000 11008 | 4,根据NSDraggingInfo Protocol ReferenceNSDragOperationPrivate | NSDragOperationGeneric&。因此,如果我们NSDragOperationGeneric使用4,我们会得到{{1}},这不是零,因此是真的。通过这种方式,我们可以检查位掩码是否包含某个标志。

答案 2 :(得分:2)

  

我知道按位AND是如何工作的,但我不明白(sourceDragMask&amp; NSDragOperationGeneric)是如何工作的,我不明白这一点。

NSDragOperationGeneric很可能是2的幂,这意味着它只有一个位集。这是故意的:位掩码几乎都被定义为两个(单个位)的幂,以启用像这样的位掩码操作。

如您所知,按位与运算仅计算两侧设置的位。如果一方只设置了一位(NSDragOperationGeneric),那么该操作将有效地测试该位是否在另一方设置。

这就是操作的重点:测试NSDragOperationGeneric位是否已设置。

有一个问题:如你所知,一个成功的按位AND测试将评估为测试位掩码, 1.因此,例如,如果你测试一个位掩码,那么定义为0x100(1后跟8个清除位),然后将该结果分配给BOOL(这是signed char)变量,您将为变量赋值为零!这就是为什么你有时会看到这样的代码:

BOOL supportsCopyOperation = ((dragOperations & NSDragOperationCopy) == NSDragOperationCopy);

或者这个:

BOOL supportsCopyOperation = ((dragOperations & NSDragOperationCopy) != 0);

或者这个:

BOOL supportsCopyOperation = !!(dragOperations & NSDragOperationCopy);

其他位掩码操作包括按位或(|)来设置值(例如return NSDragOperationCopy | NSDragOperationMove;)和按位 - 非(~,又称二进制补码)反转一个值的位,通常用于“除了”之外的任何测试。