1

我正在阅读 Apple 关于 NSDate 的文档。在他们的一个代码示例中,我看到了我以前从未见过的东西: doc link。这是示例代码。

NSDate *startDate = ...;
NSDate *endDate = ...;

NSCalendar *gregorian = [[NSCalendar alloc]
                 initWithCalendarIdentifier:NSGregorianCalendar];

NSUInteger unitFlags = NSMonthCalendarUnit | NSDayCalendarUnit;

NSDateComponents *components = [gregorian components:unitFlags
                                          fromDate:startDate
                                          toDate:endDate options:0];
NSInteger months = [components month];
NSInteger days = [components day];

我对 (OR) | 的使用感到非常困惑 将值分配给 unitFlags 时的运算符。有人能告诉我那里发生了什么吗?他们都被分配还是先检查,如果 nil 寻找另一个?先感谢您。

4

2 回答 2

2

那不是 OR 运算符 (||)。那是按位或运算符,可能是您理解的问题。

如果您查看您使用的枚举的定义,您会发现它们是为了兼容性而定义的,并且基本枚举是CFCalendarUnit. 因此,让我们看一下定义的片段CFCalendarUnit

kCFCalendarUnitEra = (1UL << 1),
kCFCalendarUnitYear = (1UL << 2),
kCFCalendarUnitMonth = (1UL << 3),
kCFCalendarUnitDay = (1UL << 4),

查看枚举已分配给的值:

kCFCalendarUnitEra = 1 leftShifted once = 2            = 00010
kCFCalendarUnitYear = 1 leftShifted twice = 4          = 00100
kCFCalendarUnitMonth = 1 leftShifted three times = 8   = 01000
kCFCalendarUnitDay = 1 leftShifted four times = 16     = 10000

请注意,二进制中的每个结果都只有一 (1) 个。

使用按位或运算符:

NSUInteger unitFlags = (NSMonthCalendarUnit | NSDayCalendarUnit)
unitFlags = 01000 (bitwise-OR) 10000

“按位”表示获取每一位并执行操作,在这种情况下为 OR

01000 |
10000 
=====
11000

然后将此值传递给您的日历,它将使用如下命令解码信息:

if (unitFlags & kCFCalendarUnitMonth == kCFCalendarUnitMonth) //Where & is the bitwise-AND operator

11000 &    //Unit Flags
01000      //Value of Month
=====
01000      //If unit flags contains month flag, month flag is returned.

使用这种技术。您可以通过“标记”每个位在单个 32 位 int 中存储 32 条布尔信息,并快速组合和检索信息。这避免了以下方法:

NSDateComponents *components = [gregorian 
                                      hasEraUnit:NO
                                      hasYearUnit:NO
                                      hasMonthUnit:YES
                                      hasDayUnit:YES
                                      hasHourUnit:NO
                                      ....
                                      hasYearForWeekOfYearUnit:NO
                                      fromDate:startDate
                                      toDate:endDate options:0];
于 2012-08-16T16:37:33.647 回答
0

他们使用这个数字作为标志。基本上,接收器将在标志上查找哪些位为 1。例如,假设您使用整数的前 4 位作为标志,您将查看这些数字中哪些是 1,哪些是零,以了解激活了标志的哪些元素。这允许您使用相同的变量来有效地传递多条信息。

于 2012-08-16T16:17:34.187 回答