31

In the latest tools, a new kind of enums are now allowed:

typedef enum CarType : NSUInteger { FourDoorCarType, TwoDoorCarType } CarType; 

My question comes in parts:

  1. Why should I use this instead of the old way?

  2. Why does CarType appear twice? I tried skipping the first CarType and just leaving the first line as "typedef enum : NSUInteger {", and it seems to work fine. What are the drawbacks, if any?

  3. Can some types other than NSUInteger be used?

2
  • 6
    +1 for raising awareness. I hadn't heard of this feature. Commented Jul 20, 2012 at 9:12
  • And you may do more with forward declaration: stackoverflow.com/a/42073610/342794 Commented Apr 30, 2018 at 17:51

6 Answers 6

37

Because this new way helps you with autocompletion, switch statement, better, respectively more precise warnings, ...

Stick with macro ...

typedef NS_ENUM( NSUInteger, CarType ) { FourDoorCarType, TwoDoorCarType }; 

... read this for example https://stackoverflow.com/a/3190470/581190

NSInteger, ... what types do you want?

Sign up to request clarification or add additional context in comments.

2 Comments

How does it help with autocompletion, switch statements, or warnings?
When you do define enum with this macro, it shows you warnings that you do not handle all possible cases in switch statement for example. Imagine you have switch statement with case FourDoorCarType: only. It warns you that you do not handle TwoDoorCarType, etc.
19
  1. This explicitly defines the numeric type that the enum uses. This helps with portability concerns. It also helps if you need control over signed vs. unsigned

  2. Two types are actually defined here. The first is enum CarType and the second is CarType, which is an alias of enum CarType. You can omit the first CarType if you want. This just prevents enum CarType from being a defined type, but CarType is still valid. Another common thing people do is something like

    typedef enum _EnumName { values } EnumName; 

    What you decide to do here is something of a matter of personal preference.

  3. Yes. You can use any numeric type, although the enum values must be able to fit in the chosen type.

3 Comments

Except that identifiers starting with an underscore followed by an uppercase letter are reserved for the implementation.
I use 't' (for 'tag') instead of the underscore, e.g.: typedef enum tMyEnum{...} MyEnum;
Does this new method allow the use of float/double?
4

One big advantage is that you can forward-declare enums with this syntax:

enum CarType : NSUInteger; 

That helps avoiding including large headers in other headers just because of enum definitions.

Comments

3

For point 2: it's the "same old syntax" from C: typedef <something> <alias>. Here, something is enum <enumIdent> { <a, b, c, d, ...> }.

You're allowed to use the same name for enumIdent and alias, simply.

Comments

1

the answers would be here for you.

typedef enum MYCARTYPE { // you could drop the ": NSInteger" part to you could drop the the MYCARTYPE name as well, if you like. FourDoorCarType, TwoDoorCarType } CarType; 

Why should I use this instead of the old way?

you can use the old way at the current stage.

Why does CarType appear twice? I tried skipping the first CarType and just leaving the first line as typedef enum : NSUInteger {, and it seems to work fine. What are the drawbacks, if any?

because you named the enum as CarType and then you named the new type in typedef definition as CarType as well. you don't need to name the enum because you cannot use its name anywhere. the name of the new type should be enough.

Can some types other than NSUInteger be used?

yep, you can, the types are always NSInteger, you don't need to limit them unsigned integer.

8 Comments

Identifiers that start with two underscores are reserved and should not be used. Similarly, identifiers that start with an underscore followed by an uppercase letter are also reserved.
you are partly right, this kind of names are really reserved: __MATH__ but for the other IDs, which starts with two underscore, there are no convention, so you can use them like __MATH.
no, I am completely correct, the C standard §7.1.3 says: All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use.
ok, in that case, you should inform the Apple about it because I haven't find any same naming convention in the Apple's Naming Conventions Guide, and they are using this way for their macros in their frameworks as well. it seems the Apple does not care of the ISO standards. :)
Apple's toolchain is the implementation though. An implementation is allowed to use reserved identifiers, but your application is not.
|
1

New NS_ENUM also enables you to forward declare as following:

// Forward declaration for XYZCharacterType in other header say XYZCharacter.h typedef NS_ENUM(NSUInteger, XYZCharacterType); // Enum declaration header: "XYZEnumType.h" #ifndef XYZCharacterType_h #define XYZCharacterType_h typedef NS_ENUM(NSUInteger, XYZEnumType) { XYZCharacterTypeNotSet, XYZCharacterTypeAgent, XYZCharacterTypeKiller, }; #endif /* XYZCharacterType_h */` 

Forward-declare enum in Objective-C

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.