这是我想要做的。我有一个简单的NS_OPTIONS设置,如
typedef NS_OPTIONS(NSUInteger, BuildingsPresent) {
NoBuildings = 0,
LadderPresent = 1 << 0,
WallPresent = 1 << 1,
RoomPresent = 1 << 2,
RoomUpgradePresent = 1 << 3
};
我设置的值如下:
self.buildingPresent |= LadderPresent | WallPresent;
这似乎工作正常,但现在我想像if语句一样测试if语句中的标志:
if (self.buildingPresent & LadderPresent & WallPresent) {
这不能正常工作。如果我将它分解为多个if语句,它似乎确实有效:
if (self.buildingPresent & LadderPresent) {
if (self.buildingPresent & WallPresent) {
//do something
}
}
我也想正确测试缺少某些东西,所以理想的写作方式是:
if (!(self.buildingPresent & RoomPresent) && (self.buildingPresent & LadderPresent & WallPresent) {
这在Objective-C中是否可行?我做错了吗?
答案 0 :(得分:5)
if (self.buildingPresent & LadderPresent & WallPresent)
这将始终评估为false。
&
运算符仅在运算符的两边都设置为1的位位置返回1,而在其他每个位置都返回0。
LadderPresent & WallPresent
没有两个位都为1的位置,因此它们将始终为全0。无论你用{0}将全零置零都是零,因此是假的。
如果您打算检查&
位和LadderPresent
位是否都处于活动状态,则需要WallPresent
这些位,然后OR
将结果变为变量:
AND
只要 EITHER if (self.buildingPresent & (LadderPresent | WallPresent)) {
和self.buildingPresent
位设置为1,对于LadderPresent
的任何值都会返回true。
为了验证 BOTH 是否设置为1,我们必须WallPresent
我们的变量到一个掩码,该掩码表示两者都被设置为1,然后看看这些掩码是否等于掩码我们想:
AND
此示例现在仅在BOTH设置为1时才返回true。
测试缺少的正确方法看起来更像是这样:
NSInteger bitMask = (LadderPresent | WallPresent)
if ((self.buildingPresent & bitMask) == bitMask) {
当(self.buildingPresent & RoomPresent) == 0
在该位置具有0时返回true,并且当它具有1时返回false。
答案 1 :(得分:3)
您可以直接在dasblinkenlight的答案中使用bit-twiddling表达式,但是如果您编写一个函数来测试多个标志,我认为您的代码会更清晰:
BOOL hasFlags(NSUInteger actualFlags, NSUInteger desiredFlags) {
return (actualFlags & desiredFlags) == desiredFlags;
}
...
if (hasFlags(self.buildingPreset, LadderPresent | WallPresent)) {
...
}
(注意:return actualFlags & desiredFlags;
中的不只是hasFlags
。这可以返回不是YES
的{true}值,{{3} }。)
同样,要检查是否缺少所有指定的标志:
BOOL lacksFlags(NSUInteger actualFlags, NSUInteger forbiddenFlags) {
return (actualFlags & forbiddenFlags) == 0;
}
...
if (lacksFlags(self.buildingPresent, RoomPresent)
&& hasFlags(self.buildingPresent, LadderPresent | WallPresent)) {
...
}