2012-08-16 22 views
1

我正在閱讀有關NSDate的Apple文檔。在他們的一個代碼示例中,我看到了一些我從未見過的東西: doc link。這是示例代碼。使用|將值分配給NSUInteger (OR)運營商?

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時。有人能告訴我發生了什麼嗎?他們都被分配了嗎?還是先檢查一下,如果沒有找到另一個?先謝謝你。

回答

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個布爾信息存儲在單個32位int中,並快速複合並檢索信息。這避免了像這樣的方法:

NSDateComponents *components = [gregorian 
             hasEraUnit:NO 
             hasYearUnit:NO 
             hasMonthUnit:YES 
             hasDayUnit:YES 
             hasHourUnit:NO 
             .... 
             hasYearForWeekOfYearUnit:NO 
             fromDate:startDate 
             toDate:endDate options:0]; 
+0

神奇的詳細解釋!真棒。謝謝。 – Matjan 2012-08-16 16:50:30

0

他們使用這個數字作爲標誌。基本上,接收器將查找標誌上的哪些位是1。例如,假設您使用整數的前4位作爲標誌,您將查看哪些數字爲1,哪些數字爲零以知道標誌的哪些元素已激活。這使您可以使用相同的變量高效地傳遞多個信息。

+0

感謝您的答案。我仍然想知道在所示的特定示例中這是如何工作的。在功能層面上,我只是將兩個整數放入一個變量(使用|),然後當我稍後調用它時再次彈出它們?如果我理解正確,他們是否按照他們的順序出來,有什麼限制?我可以分配三個變量嗎? – Matjan 2012-08-16 16:44:53

+0

檢查:http://en.wikipedia.org/wiki/Bitwise_operation – J2theC 2012-08-16 16:54:56

+0

你可以使用這種操作,例如,保存在那裏的事件重複一年中的月份。你可以說LSB是一年中的第一個月,所以,如果你有1號(000000000001基數2)意味着只有1月是活躍的。如果你有17(000000010001基數2),意味着你有1月和5月。如果你看到這個,你意識到你可以使用位標誌傳遞很多信息(取決於上下文)。 – J2theC 2012-08-16 16:57:52