un poquito

Why use NS_OPTIONS for bitmasks?

The general recommendation is to use NS_OPTIONS when defining bitmasks and, even after I contributed this pull request, I wasn’t entirely sure the reason why. Specially when you consider that both are defined exactly the same way for Objective-C:

#define CF_ENUM(_type, _name) _type _name; enum
#define CF_OPTIONS(_type, _name) _type _name; enum

The key here though, is that NS_OPTIONS is defined differently for Objective-C++:

#if (__cplusplus)
  #define CF_OPTIONS(_type, _name) _type _name; enum : _type
  #define CF_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type

This is because when OR'ring values together the C++ compiler behaves differently and treats the resulting value as the type backing the enumeration instead. For example, compiling as Objective-C++ this code would cause a compiler error:

typedef NS_ENUM(NSInteger, NYTAdRequestState) {
    NYTAdRequestStateInactive = 1 << 0,
    NYTAdRequestStateLoading  = 1 << 1
//Compile error
NYTAdRequestState* state = NYTAdRequestStateInactive | NYTAdRequestStateLoading;

However, as you can see the error goes away if we use NS_OPTIONS

In conclusion, if you’re working with bitmasks, use NS_OPTIONS and everywhere else use NS_ENUM.