What is a typedef enum in Objective-C?
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
}
Craig
Updated on August 03, 2022Comments
-
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 about 15 yearsIs the user defined type called "enum" ? That's what I had thought, until I came across code that had multiple typedef enum declarations.
-
rampion about 15 yearsNope, the user defined type is ShapeType. Read up on typedef : en.wikipedia.org/wiki/Typedef
-
gnasher729 about 10 yearsA 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 about 15 yearsNice explanation - just to add one thing, struct's follow similar naming rules in C (not sure about Objective-C).
-
sigjuice about 15 yearsObjective-C is a proper superset of C. All the C struct naming rules in C are just as valid in Objective-C.
-
user4951 about 13 yearsAwesome. Can I just use C++ style enum and also don't need to write enum :)
-
Kevin Hoffman almost 13 yearsYou 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 about 11 yearsThe part about "Enum Improvements" starts at 5:58
-
Snowcrash about 11 yearsAnd 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 over 10 yearsAs commented on another answer, see explanation of Apple’s
NS_ENUM
macro by NSHipster: NSHipster.com/ns_enum-ns_options -
NoodleOfDeath almost 10 yearsWhen would you need to give the enumeration a name? Seems to me you could always leave it anonymous?
-
YoGiN over 9 yearsThis is the link to the official documentation about NS_ENUM: developer.apple.com/library/ios/releasenotes/ObjectiveC/…
-
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 about 7 yearsI 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 over 6 yearsIf need to forward declare enum (NS_ENUM): stackoverflow.com/a/42009056/342794