I know how bitwise AND works,but I don't understand how does (sourceDragMask & NSDragOperationGeneric) work here,I don't get the point.Is there anyone can explain to me?Thanks a lot.
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
{
NSPasteboard *pboard;
NSDragOperation sourceDragMask;
sourceDragMask = [sender draggingSourceOperationMask];
pboard = [sender draggingPasteboard];
if ( [[pboard types] containsObject:NSColorPboardType] )
{
if (sourceDragMask & NSDragOperationGeneric)
{
开发者_StackOverflow中文版 return NSDragOperationGeneric;
}
}
return NSDragOperationNone;
}
NSDragOperationGeneric
is a bit-mask — probably a power of two — meaning that only one bit in the number is set. A bit-wise &
with sourceDragMask
will produce a non-zero output if and only if the corresponding bit is set in sourceDragMask
.
Hypothetically (I don't know the actual value of NSDragOperationGeneric
):
sourceDragMask: 00011010
NSDragOperationGeneric: 00001000
a & b: 00001000
In short, the if statement will succeed if sourceDragMask
has the `NSDragOperationGeneric' bit set.
sourceDragMask
is what's called a bitmask: an integer that represents a a number of boolean flags. It's declared as a variable of type NSDragOperation
, which is actually typedef
ed from NSUInteger
—it really is just that.
First off, the &
operator is what's known as a "bitwise AND", which simply takes two numbers AND
s each of the bits in them to create a new value. For example, 0011 1001 & 0101 1010 == 0001 0001
—57 & 90 = 17
. Similarly, the |
operator does a bitwise OR. Using these operators, we can use each of those 1s and 0s as a boolean flag separately.
So, if, for example, sourceDragMask
is the value 12
, what does this tell us? In binary, 12
is represented as 0000 1100
, or 8 | 4
, which according to the NSDraggingInfo Protocol Reference, is NSDragOperationPrivate | NSDragOperationGeneric
. So if we &
this with NSDragOperationGeneric
, we get 4
out, which is non-zero and therefore true. In this way, we can check whether a bitmask contains a certain flag.
I know how bitwise AND works,but I don't understand how does (sourceDragMask & NSDragOperationGeneric) work here,I don't get the point.
NSDragOperationGeneric
is most likely a power of two, which means it has only one bit set. This is deliberate: Bit masks are almost all defined as powers of two (single bits) to enable bit-mask operations like this one.
The bitwise-AND operation, as you know, evaluates to only those bits that are set in both sides. If one side has only one bit (NSDragOperationGeneric
) set, then the operation effectively tests whether that bit is set in the other side.
That's the point of the operation: To test whether the NSDragOperationGeneric
bit is set.
There is one gotcha: As you know, a successful bitwise AND test will evaluate to the tested-for bit mask, not 1. So, for example, if you test for a bit mask that's defined as 0x100 (1 followed by 8 clear bits), then assign that result to a BOOL
(which is a signed char
) variable, you'll assign zero to the variable! This is why you sometimes see code like this:
BOOL supportsCopyOperation = ((dragOperations & NSDragOperationCopy) == NSDragOperationCopy);
or this:
BOOL supportsCopyOperation = ((dragOperations & NSDragOperationCopy) != 0);
or this:
BOOL supportsCopyOperation = !!(dragOperations & NSDragOperationCopy);
Other bit-mask operations include bitwise-OR (|
) to set bits in a value (return NSDragOperationCopy | NSDragOperationMove;
, for example) and bitwise-NOT (~
, a.k.a. two's complement) to invert the bits of a value, usually for “anything but” tests.
精彩评论