例如,NSCalendar中的此方法采用位掩码:
- (NSDate *)dateByAddingComponents:(NSDateComponents *)comps toDate:(NSDate *)date options:(NSUInteger)opts
所以选项可以是:
NSUInteger options = kCFCalendarUnitYear;
或者喜欢:
NSUInteger options = kCFCalendarUnitYear | kCFCalendarUnitMonth | kCFCalendarUnitDay;
我没有得到的是,这实际上是怎么做到的?我的意思是:他们怎样才能提取合并到options
的那些值?如果我想编写这样的东西,那可能需要一个位掩码,那看起来怎么样?
答案 0 :(得分:36)
Bitmasks非常基本。你可以这样想(C#直到有人可以转换):
public enum CalendarUnits
{
kCFCalendarUnitDay = 1, // 001 in binary
kCFCalendarUnitMonth = 2, // 010 in binary
kCFCalendarUnitYear = 4, // 100 in binary
}
然后,您可以使用按位运算符组合值:
// The following code will do the following
// 001 or 100 = 101
// So the value of options should be 5
NSUInteger options = kCFCalendarUnitDay | kCFCalendarUnitYear;
此技术也经常用于安全例程:
public enum Priveledges
{
User = 1,
SuperUser = 2,
Admin = 4
}
// SuperUsers and Admins can Modify
// So this is set to 6 (110 binary)
public int modifySecurityLevel = SuperUser | Admin;
然后要检查安全级别,您可以使用按位并查看您是否有足够的权限:
public int userLevel = 1;
public int adminLevel = 4;
// 001 and 110 = 000 so this user doesn't have security
if(modifySecurityLevel & userLevel == userLevel)
// but 100 and 110 = 100 so this user does
if(modifySecurityLevel & adminLevel == adminLevel)
// Allow the action
答案 1 :(得分:32)
要执行此操作,您希望按位AND对正在测试的掩码进行测试,然后查看ANDing的结果是否等于掩码本身:
if ((options & kCFCalendarUnitYear) == kCFCalendarUnitYear) {
// do whatever
}
答案 2 :(得分:16)
Bitmasks有效,因为在二进制中,每个幂为2(即2 0 = 1,2 1 = 2,2 1 = 4)在比特序列中占据一个点。例如:
decimal | binary
1 | 0001
2 | 0010
4 | 0100
8 | 1000
当您or
(C语言中的运算符|
)将a
和b
两个数字合并为c
时,您说“取a
,b
或两者中的位并将它们放入c
。“由于2的幂表示二进制字符串中的单个位置,因此没有重叠,您可以确定设置了哪些。例如,如果我们or
2和4
0010 | 0100 = 0110
注意它基本上是如何组合这两者的。另一方面,如果我们or
5和3:
decimal | binary
5 | 0101
3 | 0011
0101 | 0011 = 0111
请注意,我们无法确定哪些位来自哪里,因为每个位的二进制表示之间存在重叠。
再一个例子,这一点变得更加明显。我们取数字1,2和4(所有2的幂)
0001 | 0010 | 0100 = 0111
这与5 | 3
的结果相同!但由于原始数字是2的幂,我们可以唯一地说出每个位的来源。
答案 3 :(得分:6)
关键是要记住,您合并到“选项”中的每个值实际上只是一个数字。我不确定你对二进制文件有多熟悉,但你可以用十进制来考虑它而只是添加数字而不是对它们进行OR运算。
假设A = 10,B = 100,C = 1000
如果你想设置options = A + B,那么选项将等于110.你调用的方法将查看A的“十”位置,B的“数百”位置和“千位”位置对于C.在这个例子中,有一个是数百位和十位,所以该方法会知道A和B是在选项中设置的。
由于计算机使用二进制而非十进制,这有点不同,但我认为这个想法非常相似,有时在熟悉的编号系统中更容易思考。
答案 4 :(得分:3)
typedef NS_OPTIONS(NSUInteger, MyOption)
{
OptionNone = 0,
OptionOne = 1 << 0,
OptionTwo = 1 << 1,
OptionThree = 1 << 2
};
if (givenValue & OptionOne) {
// bit one is selected
}
if (givenValue & OptionTwo) {
// bit two is selected
}
答案 5 :(得分:0)
我发现Calculator.app有助于可视化位掩码。 (只需选择View&gt; Programmer,然后单击按钮显示二进制)。 (您可以单击二进制表中的任何0或1来打开或关闭这些位;或者,输入十进制或十六进制的数字(使用8 | 10 | 16 NSSegmentedControl在不同的表示之间切换)。)