协慌网

登录 贡献 社区

Objective-C 中的 typedef 枚举是什么?

我不认为我从根本上理解enum是什么,以及何时使用它。

例如:

typedef enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} ShapeType;

这里真的被宣布了什么?

答案

这里声明了三件事:声明了一个匿名枚举类型, ShapeType被声明为该匿名枚举的 typedef,并且三个名称kCirclekRectanglekOblateSpheroid被声明为整数常量。

让我们打破它。在最简单的情况下,枚举可以声明为

enum tagname { ... };

这声明了带有标记tagname的枚举。在 C 和 Objective-C(但不是 C ++)中,对此的任何引用都必须enum关键字开头。例如:

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

为了避免在任何地方使用enum关键字,可以创建一个 typedef:

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

这可以简化为一行:

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

最后,如果我们不需要能够将enum tagnameenum关键字一起使用,我们可以使enum匿名并仅使用 typedef 名称声明它:

typedef enum { ... } tagname;

现在,在这种情况下,我们将ShapeType声明为匿名枚举的 typedef 名称。 ShapeType实际上只是一个整数类型,并且只应用于声明包含声明中列出的值之一的变量(即kCirclekRectanglekOblateSpheroid )。但是,您可以通过强制转换为ShapeType变量指定另一个值,因此在读取枚举值时必须小心。

最后, kCirclekRectanglekOblateSpheroid在全局命名空间中声明为整数常量。由于未指定特定值,因此将它们分配kCircle 0 开头的连续整数,因此kCircle为 0, kRectangle为 1, kOblateSpheroid为 2。

Apple 建议自 Xcode 4.4 以来定义这样的枚举:

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

它们还提供了一个方便的宏 NS_ENUM:

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

这些定义提供更强的类型检查和更好的代码完成。我找不到 NS_ENUM 的官方文档,但您可以在此处观看 WWDC 2012 会议中的 “Modern Objective-C” 视频。

UPDATE:链接到官方文档在这里

枚举声明了一组有序值 - typedef 只是为此添加了一个方便的名称。第一个元素是 0 等

typedef enum {
Monday=1,
...
} WORKDAYS;

WORKDAYS today = Monday;

以上只是 shapeType 标签的枚举。