NoobOverflow
NoobOverflow

Reputation: 1288

The new enum in Objective-C

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?

Upvotes: 31

Views: 12141

Answers (6)

lal
lal

Reputation: 8130

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

Upvotes: 1

Jorge Vasquez
Jorge Vasquez

Reputation: 583

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.

Upvotes: 4

holex
holex

Reputation: 24041

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.

Upvotes: 1

zrzka
zrzka

Reputation: 21219

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?

Upvotes: 37

Lily Ballard
Lily Ballard

Reputation: 185653

  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.

Upvotes: 19

Cyrille
Cyrille

Reputation: 25144

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.

Upvotes: 3

Related Questions