2013-08-02 103 views
0

我讀文檔NSCalendar和好奇,我更深入地CFCalendarUnit,我看到這一點:枚舉Objective-C和「<<」操作符

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

我無法弄清楚。怎麼運行的?

+0

2 + 3 + 8 + 16 = 30. 2 + 4 + 8 + 16 + 32 + 64 = 124.你的問題到底是什麼?自然地,按位OR操作數恰好等於+,因爲每個操作數總是隻有一個唯一的位。 –

+0

是的,在你下面有很多人回答之前。只是要清楚... 2 + 3 + 8 + 16不是30 ... 2 + 4 + 8 + 16是。 – Kuba

+0

當然,我打算寫2 + 4 + 8 ... –

回答

5

這些只是二進制數。 1 << n是一個二進制數,1n的第零位以及其他地方的零。爲了找出其中若干OR -ed在一起的值,寫入對應於有多少職位被1在其定義移者的位置的二進制數,而且這個數字轉換爲十進制表示。

例如,

NSEraCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit 

在位置1(時代)的,2(年),3(月)和4(日),零點在所有其餘位置;位置從右開始從零開始編號。它看起來像這樣:

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

00011110的二進制形式是十進制表示30

1

當你寫(1 << k)你獲得只有第k個(從右邊開始,基於0)比特被接通。如果你寫(1 << a) | (1 << b)你得到只有第一和第二位被設置。

當您獲得124,例如,你正在處理的二進制數1111100.這意味着你結合在一起(或操作者)的人數這樣

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

。我不知道這是否意味着中您的符號名稱的條款,因爲它看起來你複製了錯誤的枚舉。但我相信你明白了! :)

1

|是位或運算符。它採用兩個長度相等的模式,並在每對相應位上執行邏輯包含或操作。所以簡而言之,它需要NSYearCalendarUnit,NSMonthCalendarUnit等,並執行OR操作,這會導致您的12430。這是傳遞標誌組合作爲參數的常用方式。

3

枚舉是使用按位移操作(wiki)以產生其中每個只設定一個位在用於存儲到枚舉值的「INT」值。通過這樣做,您可以對這些值進行或運算(按位運算),並仍能夠確定設置了哪些選項。

查看preservedComponents作爲實際數字確實意味着什麼,但它並不是很明顯,因爲它意味着一組指定格式/掩碼中的選定位。