枚举目标-C 和"<<"运算符

enum objective-C and "<<" operator

本文关键字:lt 运算符 目标 枚举      更新时间:2023-10-16

我正在阅读文档以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.

我想不通。它是如何工作的?

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

例如

NSEraCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit

在位置 1(纪元(、2(年(、3(月(和4(日(中有一个,在所有剩余位置中都有零;位置从右边开始编号为零。它看起来像这样:

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

二进制表示中的此00011110在十进制表示中30

枚举

使用按位移位操作(wiki(来生成值,每个值在用于存储枚举值的"int"中仅设置一个位。通过执行此操作,您可以将值放在一起 OR(按位运算(,并且仍然能够分辨设置了哪些选项。

preservedComponents视为实际数字确实有意义,但并不明显,因为它的意思是一组指定格式/掩码的选定位。

当你写(1 << k)时,你得到的只有第k位(从右边开始,从0开始(位被打开。如果写入(1 << a) | (1 << b)则只会设置第 a 位和第 b 位。

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

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

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

|是按位的 OR 运算符。它采用两个长度相等的位模式,并对每对相应位执行逻辑包含 OR 运算。所以简单地说,它需要NSYearCalendarUnit,NSMonthCalendarUnit等并执行OR操作,从而产生12430。这是将标志组合作为参数传递的非常常见的方式。