views:

31

answers:

1

I just looked at the code in NSCalendar.h like this:

enum {
    NSEraCalendarUnit = kCFCalendarUnitEra,
    NSYearCalendarUnit = kCFCalendarUnitYear,
    NSMonthCalendarUnit = kCFCalendarUnitMonth,
    NSDayCalendarUnit = kCFCalendarUnitDay,
    NSHourCalendarUnit = kCFCalendarUnitHour,
    NSMinuteCalendarUnit = kCFCalendarUnitMinute,
    NSSecondCalendarUnit = kCFCalendarUnitSecond,
    NSWeekCalendarUnit = kCFCalendarUnitWeek,
    NSWeekdayCalendarUnit = kCFCalendarUnitWeekday,
    NSWeekdayOrdinalCalendarUnit = kCFCalendarUnitWeekdayOrdinal,
};
typedef NSUInteger NSCalendarUnit;

And in client code, I can call something like:

NSUInteger unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSWeekCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
    NSDateComponents *dateComponents = [calendar components:unitFlags
                                                   fromDate:self
                                                     toDate:[NSDate date]
                                                    options:0];

I don't really get the way this code works.

How can they define an anonymous enum and then define the type of NSCalendarUnit to be NSUInteger. And how can they link between the NSCalendarUnit and the anonymous enum.

And in client code, I can do OR operation with NSUInteger, then how they (the NSCalendar) parse it out to know what kinds of elements I need to give it back to me?

+1  A: 

They're pulled out using the & operator. This is called a bitfield, and Wikipedia has an OK article on how they work: http://en.wikipedia.org/wiki/Bit_field

I also answered a question recently on how bitwise operators work: http://stackoverflow.com/questions/3427585#3427633

Dave DeLong
int MagicMap = 1;int MagicWand = 2;int MagicHat = 4;About this block of code for bit mask, does it need to be 2^n, because I just wonder why int MagicHat = 4 instead of 3? Is it because of '(1 | 2) = 3'
vodkhang
And then how can you define anonymous enum like enum {}; typedef NSUInteger NSCalendarUnit; ?
vodkhang
@vodkhang yes, the values must be powers of 2, as you've correctly figured out. And the typedef is just for semantic clarity, and doesn't actually affect anything. Just helps the programmer realize what the purpose of the value is. `NSCalendarUnit`, in this context, is a lot more sensical than `NSUInteger`.
Dave DeLong
ah yeah, I got it
vodkhang