Swift

NSCalendarUnitはなにをしているのか

More than 3 years have passed since last update.

iOS初心者です

カレンダーを表示しようとしたときに

let now = NSDate()
let calendar = NSCalendar.currentCalendar()
let flag = NSCalendarUnit.CalendarUnitYear  |
           NSCalendarUnit.CalendarUnitMonth |
           NSCalendarUnit.CalendarUnitDay   |
           NSCalendarUnit.CalendarUnitHour

calendar.components(flag, fromDate: now) // 日付を取得!

こんなかんじのものが出てきました。
calendar.componentsにflagと現在時刻を渡せばよいみたいなのですが、 このflagがなにをしているのかどうも分かりません。

調べてみました。

まずflagの生成に使われている | はbit演算子のOR です。playgroundで見ると分かりやすいですが

まずは一つの時

var flag  = NSCalendarUnit.CalendarUnitYear // {rawValue: 4}

となり、なにか値を持っているようです。

つぎに2つにすると

var flag  = NSCalendarUnit.CalendarUnitYear | NSCalendarUnit.CalendarUnitMonth // {rawValue: 12}

値が増えた!OR演算子を使ってビットを立てているので値が増えるわけですね。

つまり、flagで立てられているbitの部分によって、calendar.component メソッドは返り値を変えるようです。

ここで objective-c側の NSCalendarUnit の定義を見てみると

enum {
    NSEraCalendarUnit               = 1 << 1,
    NSYearCalendarUnit              = 1 << 2,
    NSMonthCalendarUnit             = 1 << 3,
    NSDayCalendarUnit               = 1 << 4,
    NSHourCalendarUnit              = 1 << 5,
    NSMinuteCalendarUnit            = 1 << 6,
    NSSecondCalendarUnit            = 1 << 7,
    NSWeekCalendarUnit              = 1 << 8,
    NSWeekdayCalendarUnit           = 1 << 9,
    NSWeekdayOrdinalCalendarUnit    = 1 << 10
};

こうなってます。 << で左シフトして、10桁までのbitのうちそれぞれ1つづつが立ててある定数を定義しているみたいです。

先ほど

var flag  = NSCalendarUnit.CalendarUnitYear // {rawValue: 4}

で4だったのは CalendarUnitYear1<<2、つまり 2進数で 100 なので、10進数に直して 4だったわけです

つまりこれも、

var flag  = NSCalendarUnit.CalendarUnitYear | NSCalendarUnit.CalendarUnitMonth // {rawValue: 12}

0100 と 1000 を OR演算しているので、 110012、というわけでした。

iOS初心者すぎて理解が微妙ですが、bitを使って場合分けをするの、なかなか便利そうですね。
component メソッドが中でどのようにflagを処理しているのかまで調べたかったですがまた今度