0

我正在阅读文档NSCalendar,出于好奇,我更深入地研究CFCalendarUnit并看到了这一点:

typedef enum {
   kCFCalendarUnitEra = (1 << 1),
   kCFCalendarUnitYear = (1 << 2),
   kCFCalendarUnitMonth = (1 << 3),
   kCFCalendarUnitDay = (1 << 4),
   kCFCalendarUnitHour = (1 << 5),
   kCFCalendarUnitMinute = (1 << 6),
   kCFCalendarUnitSecond = (1 << 7),
   kCFCalendarUnitWeek = (1 << 8),
   kCFCalendarUnitWeekday = (1 << 9),
   kCFCalendarUnitWeekdayOrdinal = (1 << 10),
   kCFCalendarUnitQuarter = (1UL << 11),
   kCFCalendarUnitWeekOfMonth = (1UL << 12),
   kCFCalendarUnitWeekOfYear = (1UL << 13),
   kCFCalendarUnitYearForWeekOfYear = (1UL << 14),
} CFCalendarUnit;

我正在使用这个:

NSUInteger preservedComponents = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit;

它回来了124

所以我尝试这样做:

NSUInteger preservedComponents = NSEraCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;

我明白了30

我想不通。这个怎么运作?

4

4 回答 4

5

这些只是二进制数。1 << n是一个二进制数,1n-th 位置,其他位置为零。要找出其中几个的值OR,请写一个二进制数,其位置对应于在其定义中移动了多少个位置1,并将该数字转换为十进制表示。

例如,

NSEraCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit

在位置1(时代)、2(年)、3(月)和4(日)中具有 1,在所有剩余位置中具有 0;位置从右侧开始从零开始编号。它看起来像这样:

Position:  76543210
           --------
Bit value: 00011110

00011110以二进制表示是30十进制表示。

于 2013-08-02T15:10:38.220 回答
3

枚举使用按位移位操作 ( wiki ) 来生成值,每个值在用于存储枚举值的“int”中仅设置一位。通过这样做,您可以对这些值进行 OR(按位运算),并且仍然能够判断设置了哪些选项。

preservedComponents视为实际数字确实意味着某些东西,但这并不是很明显,因为它的含义是指定格式/掩码中的一组选定位。

于 2013-08-02T15:11:59.850 回答
1

当您编写时,您(1 << k)会发现只有第 k 个(从右侧开始,基于 0)位被打开。如果你写(1 << a) | (1 << b),你会得到只有 a-th 和 b-th 位被设置。

例如,当您获得 124 时,您正在处理二进制数 1111100。这意味着您以这种方式将数字组合在一起(或运算符)

(1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) | (i << 6)

我不知道这对您的符号名称意味着什么,因为您似乎复制了错误的枚举。但我相信你明白了!:)

于 2013-08-02T15:11:02.827 回答
1

|是按位或运算符。它采用两个长度相等的位模式,并对每对相应的位执行逻辑异或运算。所以很快地说,它需要 NSYearCalendarUnit、NSMonthCalendarUnit 等并执行 OR 操作,结果是你的124and 30。这是将标志组合作为参数传递的非常常见的方式。

于 2013-08-02T15:11:31.193 回答