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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/707512/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 21:20:44  来源:igfitidea点击:

What is a typedef enum in Objective-C?

objective-cenumstypedef

提问by Craig

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

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

For example:

例如:

typedef enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} ShapeType;

What is really being declared here?

这里真正宣布的是什么?

回答by Adam Rosenfield

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

三件事正在这里声明:匿名枚举类型声明,ShapeType在声明该匿名枚举一个typedef和三个名字kCirclekRectanglekOblateSpheroid被声明为整型常量。

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 notC++), any references to this mustbe preceded with the enumkeyword. For example:

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

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 enumkeyword everywhere, a typedef can be created:

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

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 tagnamewith the enumkeyword, we can make the enumanonymous and only declare it with the typedef name:

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

typedef enum { ... } tagname;

Now, in this case, we're declaring ShapeTypeto be a typedef'ed name of an anonymous enumeration. ShapeTypeis 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 ShapeTypevariable another value by casting, though, so you have to be careful when reading enum values.

现在,在这种情况下,我们声明ShapeType为匿名枚举的 typedef 名称。 ShapeType实际上只是一个整数类型,且只能用于声明持有在声明中列出的其中一个值(也就是一个变量kCirclekRectanglekOblateSpheroid)。但是,您可以ShapeType通过强制转换为变量分配另一个值,因此在读取枚举值时必须小心。

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

最后,kCirclekRectanglekOblateSpheroid被声明为全局命名空间中的整数常量。由于没有指定特定值,它们被分配给从 0 开始的连续整数,因此kCircle0、1kRectanglekOblateSpheroid2 也是如此。

回答by Vladimir Grigorov

Apple recommends defining enums like this since Xcode 4.4:

Xcode 4.4 开始,Apple 建议像这样定义枚举:

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

They also provide a handy macro NS_ENUM:

他们还提供了一个方便的宏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.

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



UPDATE
Link to official documentation here.

更新
官方文档链接在这里

回答by hburde

An enum declares a set of ordered values - the typedef just adds a handy name to this. The 1st element is 0 etc.

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

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

WORKDAYS today = Monday;

The above is just an enumeration of shapeType tags.

以上只是对 shapeType 标签的枚举。

回答by Brian Mitchell

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).

具有的可能值的用户定义的类型kCirclekRectanglekOblateSpheroid。不过,枚举内部的值(kCircle 等)在枚举外部可见。记住这一点很重要(int i = kCircle;例如,是有效的)。

回答by Mani

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

64 位更改的更新:根据苹果文档关于 64 位更改,

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

枚举也是类型化的:在 LLVM 编译器中,枚举类型可以定义枚举的大小。这意味着某些枚举类型的大小也可能比您预期的要大。与所有其他情况一样,解决方案是不对数据类型的大小做任何假设。相反,将任何枚举值分配给具有正确数据类型的变量

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

因此,如果您支持 64 位,则必须创建具有以下语法类型的枚举

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

否则,它将导致警告为 Implicit conversion loses integer precision: NSUInteger (aka 'unsigned long') to ShapeType

Update for swift-programming:

快速编程的更新:

In swift, there's an syntax change.

在 swift 中,有一个语法更改。

enum ControlButtonID: NSUInteger {
        case kCircle , kRectangle, kOblateSpheroid
    }

回答by Vincent Zgueb

The enum (abbreviation of enumeration) is used to enumerate a set of values (enumerators). A value is an abstract thing represented by a symbol (a word). For example, a basic enum could be

枚举(enumeration 的缩写)用于枚举一组值(枚举数)。值是由符号(一个词)表示的抽象事物。例如,一个基本的枚举可以是

enum { xs,s,m,l,xl,xxl,xxxl,xxxxl };

This enum is called anonymous because you do not have a symbol to name it. But it is still perfectly correct. Just use it like this

这个枚举被称为匿名,因为你没有一个符号来命名它。但它仍然是完全正确的。像这样使用它

enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize;

Ok. The life is beautiful and everything goes well. But one day you need to reuse this enum to define a new variable to store myGrandFatherPantSize, then you write:

好的。生活很美好,一切都很顺利。但是有一天你需要重用这个枚举来定义一个新变量来存储 myGrandFatherPantSize,然后你写:

enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize;
enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandFatherPantSize;

But then you have a compiler error "redefinition of enumerator". Actually, the problem is that the compiler is not sure that you first enum and you are second describe the same thing.

但是你有一个编译器错误“重新定义枚举器”。实际上,问题在于编译器不确定您首先是枚举,然后是第二个描述相同的事情。

Then if you want to reuse the same set of enumerators (here xs...xxxxl) in several places you must tag it with a unique name. The second time you use this set you just have to use the tag. But don't forget that this tag does not replace the enum word but just the set of enumerators. Then take care to use enum as usual. Like this:

然后,如果您想在多个位置重复使用相同的枚举器集(此处为 xs...xxxxl),您必须用唯一的名称标记它。第二次使用这个集合时,你只需要使用标签。但是不要忘记这个标签不会替换枚举词,而只是替换枚举器集。然后照常使用枚举。像这样:

// Here the first use of my enum
enum sizes { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize; 
// here the second use of my enum. It works now!
enum sizes myGrandFatherPantSize;

you can use it in a parameter definition as well:

您也可以在参数定义中使用它:

// Observe that here, I still use the enum
- (void) buyANewDressToMyGrandMother:(enum sizes)theSize;

You could say that rewriting enum everywhere is not convenient and makes the code looks a bit strange. You are right. A real type would be better.

你可以说到处重写 enum 并不方便,而且使代码看起来有点奇怪。你是对的。真正的类型会更好。

This is the final step of our great progression to the summit. By just adding a typedef let's transform our enum in a real type. Oh the last thing, typedef is not allowed within your class. Then define your type just above. Do it like this:

这是我们向峰会迈进的最后一步。只需添加一个 typedef,让我们将枚举转换为真实类型。哦,最后一件事,您的班级中不允许使用 typedef。然后在上面定义您的类型。像这样做:

// enum definition
enum sizes { xs,s,m,l,xl,xxl,xxxl,xxxxl };
typedef enum sizes size_type

@interface myClass {
   ...
   size_type myGrandMotherDressSize, myGrandFatherPantSize;
   ...
}

Remember that the tag is optional. Then since here, in that case, we do not tag the enumerators but just to define a new type. Then we don't really need it anymore.

请记住,标签是可选的。然后从这里开始,在这种情况下,我们不标记枚举数,而只是定义一个新类型。那么我们真的不再需要它了。

// enum definition
typedef enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } size_type;

@interface myClass : NSObject {
  ...
  size_type myGrandMotherDressSize, myGrandFatherPantSize;
  ...
}
@end

If you are developing in Objective-C with XCode I let you discover some nice macros prefixed with NS_ENUM. That should help you to define good enums easily and moreover will help the static analyzer to do some interesting checks for you before to compile.

如果您使用 XCode 在 Objective-C 中进行开发,我会让您发现一些以 NS_ENUM 为前缀的不错的宏。这应该可以帮助您轻松定义好的枚举,而且将帮助静态分析器在编译之前为您做一些有趣的检查。

Good Enum!

好枚举!

回答by Rajneesh071

typedefis useful for redefining the name of an existing variable type. It provides short & meaningful way to call a datatype. e.g:

typedef对于重新定义现有变量类型的名称很有用。它提供了调用数据类型的简短而有意义的方法。例如:

typedef unsigned long int TWOWORDS;

here, the type unsigned long int is redefined to be of the type TWOWORDS. Thus, we can now declare variables of type unsigned long int by writing,

在这里,类型 unsigned long int 被重新定义为 TWOWORDS 类型。因此,我们现在可以通过编写来声明 unsigned long int 类型的变量,

TWOWORDS var1, var2;

instead of

代替

unsigned long int var1, var2;

回答by Vivek Sehrawat

typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;

then you can use it like :-

然后你可以像这样使用它:-

 ShapeType shape;

and

 enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} 
ShapeType;

now you can use it like:-

现在你可以像这样使用它:-

enum ShapeType shape;

回答by Priyanka Naik

enum is used to assign value to enum elements which cannot be done in struct. So everytime instead of accessing the complete variable we can do it by the value we assign to the variables in enum. By default it starts with 0 assignment but we can assign it any value and the next variable in enum will be assigned a value the previous value +1.

enum 用于为 enum 元素分配值,这些元素不能在 struct 中完成。因此,每次我们都可以通过分配给 enum 中的变量的值来代替访问完整变量。默认情况下,它以 0 赋值开始,但我们可以为它赋值任何值,枚举中的下一个变量将被赋值为前一个值 +1。

回答by Bilal Arslan

You can use in the below format, Raw default value starting from 0, so

您可以使用以下格式,原始默认值从 0 开始,因此

  • kCircle is 0,
  • kRectangle is 1,
  • kOblateSpheroid is 2.
  • kCircle 为 0,
  • kRectangle 为 1,
  • kOblateSpheroid 为 2。

You can assign your own specific start value.

您可以指定自己的特定起始值。

typedef enum : NSUInteger {
    kCircle, // for your value; kCircle = 5, ...
    kRectangle,
    kOblateSpheroid
} ShapeType;

ShapeType circleShape = kCircle;
NSLog(@"%lu", (unsigned long) circleShape); // prints: 0