Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between NS_ENUM and NS_OPTIONS?

I preprocessed following code with clang in Xcode5.

typedef NS_ENUM(NSInteger, MyStyle) {     MyStyleDefault,     MyStyleCustom };  typedef NS_OPTIONS(NSInteger, MyOption) {     MyOption1 = 1 << 0,     MyOption2 = 1 << 1, }; 

And got this.

typedef enum MyStyle : NSInteger MyStyle; enum MyStyle : NSInteger {     MyStyleDefault,     MyStyleCustom };  typedef enum MyOption : NSInteger MyOption; enum MyOption : NSInteger {     MyOption1 = 1 << 0,     MyOption2 = 1 << 1, }; 

I know NS_OPTIONS is for a bitmask, but is there any technical differences? Or this is just for naming convention?

EDIT

According to the definition of NS_OPTIONS, it's probably for compiler compatibility.(especially for c++ compiler)

// In CFAvailability.h // Enums and Options #if (__cplusplus && __cplusplus >= 201103L && (__has_extension(cxx_strong_enums) || __has_feature(objc_fixed_enum))) || (!__cplusplus && __has_feature(objc_fixed_enum))   #define CF_ENUM(_type, _name) enum _name : _type _name; enum _name : _type   #if (__cplusplus)     #define CF_OPTIONS(_type, _name) _type _name; enum : _type   #else     #define CF_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type   #endif #else   #define CF_ENUM(_type, _name) _type _name; enum   #define CF_OPTIONS(_type, _name) _type _name; enum #endif 

__cplusplus value in clang is 199711 and I can't test what this is exactly for, though.

like image 987
taichino Avatar asked Sep 23 '13 15:09

taichino


People also ask

What is Ns_enum?

First, NS_ENUM uses a new feature of the C language where you can specify the underlying type for an enum. In this case, the underlying type for the enum is NSInteger (in plain C it would be whatever the compiler decides, char, short, or even a 24 bit integer if the compiler feels like it).

What is enum in Objective C?

typedef enum declaration in Objective-CA enum declares a set of ordered values - the typedef just adds a handy name to this. The 1st element is 0 etc. typedef enum { Monday=1, Tuesday, Wednesday } WORKDAYS; WORKDAYS today = Monday;//value 1.


2 Answers

There's a basic difference between an enum and a bitmask (option). You use an enum to list exclusive states. A bitmask is used when several properties can apply at the same time.

In both cases you use integers, but you look at them differently. With an enum you look at the numerical value, with bitmasks you look at the individual bits.

typedef NS_ENUM(NSInteger, MyStyle) {     MyStyleDefault,     MyStyleCustom }; 

Will only represent two states. You can simply check it by testing for equality.

switch (style){     case MyStyleDefault:         // int is 0     break;     case MyStyleCustom:         // int is 1     break; } 

While the bitmask will represent more states. You check for the individual bits with logic or bitwise operators.

typedef NS_OPTIONS(NSInteger, MyOption) {     MyOption1 = 1 << 0, // bits: 0001     MyOption2 = 1 << 1, // bits: 0010 };  if (option & MyOption1){ // last bit is 1     // bits are 0001 or 0011 } if (option & MyOption2){ // second to last bit is 1     // bits are 0010 or 0011 } if ((option & MyOption1) && (option & MyOption2)){ // last two bits are 1     // bits are 0011 } 

tl;dr An enum gives names to numbers. A bitmask gives names to bits.

like image 187
orkoden Avatar answered Sep 28 '22 03:09

orkoden


The only major difference is that using the appropriate macro allows Code Sense (Xcode's code completion) to do type checking and code completion better. For example, NS_OPTIONS allows the compiler to make sure all the enums you | together are of the same type.

For further reading see: http://nshipster.com/ns_enum-ns_options/

Edit:

Now that Swift is coming, using NS_ENUM/OPTIONS is highly recommended so that the enum can be correctly bridged to a swift enum.

like image 41
Lance Avatar answered Sep 28 '22 04:09

Lance