What is a typedef enum in Objective-C?

453,604

Solution 1

Three things are being declared here: an anonymous enumerated type is declared, ShapeType is being declared a typedef for that anonymous enumeration, and the three names kCircle, kRectangle, and kOblateSpheroid are being declared as integral constants.

Let's break that down. In the simplest case, an enumeration can be declared as

enum tagname { ... };

This declares an enumeration with the tag tagname. In C and Objective-C (but not C++), any references to this must be preceded with the enum keyword. For example:

enum tagname x;  // declare x of type 'enum tagname'
tagname x;  // ERROR in C/Objective-C, OK in C++

In order to avoid having to use the enum keyword everywhere, a typedef can be created:

enum tagname { ... };
typedef enum tagname tagname;  // declare 'tagname' as a typedef for 'enum tagname'

This can be simplified into one line:

typedef enum tagname { ... } tagname;  // declare both 'enum tagname' and 'tagname'

And finally, if we don't need to be able to use enum tagname with the enum keyword, we can make the enum anonymous and only declare it with the typedef name:

typedef enum { ... } tagname;

Now, in this case, we're declaring ShapeType to be a typedef'ed name of an anonymous enumeration. ShapeType is really just an integral type, and should only be used to declare variables which hold one of the values listed in the declaration (that is, one of kCircle, kRectangle, and kOblateSpheroid). You can assign a ShapeType variable another value by casting, though, so you have to be careful when reading enum values.

Finally, kCircle, kRectangle, and kOblateSpheroid are declared as integral constants in the global namespace. Since no specific values were specified, they get assigned to consecutive integers starting with 0, so kCircle is 0, kRectangle is 1, and kOblateSpheroid is 2.

Solution 2

Apple recommends defining enums like this since Xcode 4.4:

typedef enum ShapeType : NSUInteger {
    kCircle,
    kRectangle,
    kOblateSpheroid
} ShapeType;

They also provide a handy macro NS_ENUM:

typedef NS_ENUM(NSUInteger, ShapeType) {
    kCircle,
    kRectangle,
    kOblateSpheroid
};

These definitions provide stronger type checking and better code completion. I could not find official documentation of NS_ENUM, but you can watch the "Modern Objective-C" video from WWDC 2012 session here.


UPDATE
Link to official documentation here.

Solution 3

An 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,
...
} WORKDAYS;

WORKDAYS today = Monday;

The above is just an enumeration of shapeType tags.

Solution 4

A user defined type that has the possible values of kCircle, kRectangle, or kOblateSpheroid. The values inside the enum (kCircle, etc) are visible outside the enum, though. It's important to keep that in mind (int i = kCircle; is valid, for example).

Solution 5

Update for 64-bit Change: According to apple docs about 64-bit changes,

Enumerations Are Also Typed : In the LLVM compiler, enumerated types can define the size of the enumeration. This means that some enumerated types may also have a size that is larger than you expect. The solution, as in all the other cases, is to make no assumptions about a data type’s size. Instead, assign any enumerated values to a variable with the proper data type

So you have to create enum with type as below syntax if you support for 64-bit.

typedef NS_ENUM(NSUInteger, ShapeType) {
    kCircle,
    kRectangle,
    kOblateSpheroid
};

or

typedef enum ShapeType : NSUInteger {
   kCircle,
   kRectangle,
   kOblateSpheroid
} ShapeType;

Otherwise, it will lead to warning as Implicit conversion loses integer precision: NSUInteger (aka 'unsigned long') to ShapeType

Update for swift-programming:

In swift, there's an syntax change.

enum ControlButtonID: NSUInteger {
        case kCircle , kRectangle, kOblateSpheroid
    }
Share:
453,604
Craig
Author by

Craig

Updated on August 03, 2022

Comments

  • Craig
    Craig almost 2 years

    I don't think I fundamentally understand what an enum is, and when to use it.

    For example:

    typedef enum {
        kCircle,
        kRectangle,
        kOblateSpheroid
    } ShapeType;
    

    What is really being declared here?

    • Craig
      Craig about 15 years
      Is the user defined type called "enum" ? That's what I had thought, until I came across code that had multiple typedef enum declarations.
    • rampion
      rampion about 15 years
      Nope, the user defined type is ShapeType. Read up on typedef : en.wikipedia.org/wiki/Typedef
    • gnasher729
      gnasher729 about 10 years
      A typedef in Objective-C is exactly the same as a typedef in C. And an enum in Objective-C is exactly the same as an enum in C. This declares an enum with three constants kCircle = 0, kRectangle = 1 and kOblateSpheroid = 2, and gives the enum type the name ShapeType. If you don't know what "typedef" and "enum" means, buy a book about C.
  • Michael Burr
    Michael Burr about 15 years
    Nice explanation - just to add one thing, struct's follow similar naming rules in C (not sure about Objective-C).
  • sigjuice
    sigjuice about 15 years
    Objective-C is a proper superset of C. All the C struct naming rules in C are just as valid in Objective-C.
  • user4951
    user4951 about 13 years
    Awesome. Can I just use C++ style enum and also don't need to write enum :)
  • Kevin Hoffman
    Kevin Hoffman almost 13 years
    You can use C++ style enums if the file in which you declare them is a .mm file rather than a .m. Objective-C++ is absurdly powerful.
  • vikingosegundo
    vikingosegundo about 11 years
    The part about "Enum Improvements" starts at 5:58
  • Snowcrash
    Snowcrash about 11 years
    And once you've got your head around this answer it's worth looking at the new NS_ENUM and NS_OPTIONS. Tutorial here: nshipster.com/ns_enum-ns_options and SO here: stackoverflow.com/questions/14080750/…
  • Basil Bourque
    Basil Bourque over 10 years
    As commented on another answer, see explanation of Apple’s NS_ENUM macro by NSHipster: NSHipster.com/ns_enum-ns_options
  • NoodleOfDeath
    NoodleOfDeath almost 10 years
    When would you need to give the enumeration a name? Seems to me you could always leave it anonymous?
  • YoGiN
    YoGiN over 9 years
    This is the link to the official documentation about NS_ENUM: developer.apple.com/library/ios/releasenotes/ObjectiveC/…
  • Jake T.
    Jake T. over 7 years
    "Finally .... are declared as integral constants in the global namespace" Does this mean I can use them outside of the file I created them in, even if it's a .m? Will it cause issues to declare the same integral constants in another anonymously typedef'ed enum in another file? Is there a recommended place to declare these types of constants that may be used commonly across your app?
  • rak appdev
    rak appdev about 7 years
    I always thought "why would anyone answer a question which is already answered and accepted". Boy, I was wrong all the time! This is the best answer and helps beginners like me!
  • lal
    lal over 6 years
    If need to forward declare enum (NS_ENUM): stackoverflow.com/a/42009056/342794