ns_enum - objective-c枚举




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

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”视频。

更新:链接到here官方文档。

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

例如:

typedef enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} ShapeType;

这里真的宣布了什么?


Typedef是C和C ++中的关键字。 它用于为基本数据类型(char,int,float,double,struct和enum)创建新名称。

typedef enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} ShapeType;

在这里它创建了枚举数据类型ShapeType ,我们可以为枚举类型ShapeType编写新名称,如下所示

ShapeType shape1; 
ShapeType shape2; 
ShapeType shape3;

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

typedef unsigned long int TWOWORDS;

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

TWOWORDS var1, var2;

代替

unsigned long int var1, var2;

更新64位更改:根据有关64位更改的Apple文档

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

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

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

要么

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

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

更新快速编程:

在迅速,有一个语法变化。

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

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

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

WORKDAYS today = Monday;

以上只是shapeType标签的枚举。


枚举是用户定义的数据类型。 枚举的数据类型枚举的数据类型变量只能假定先前已声明的值。

enum month { jan = 1, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec };
enum month this_month;

this_month = feb;

在上面的声明中,month被声明为一个枚举数据类型。 它由一组值,1月至12月。 在数值上,jan的值为1,feb的值为2,依此类推。

变量this_month被声明为与月份相同的类型,然后分配与feb相关联的值。 This_month不能被指定为在月份声明的初始化列表中指定的值以外的任何值。


枚举(枚举的缩写)用于枚举一组值(枚举器)。 值是由符号(一个词)表示的任何抽象事物。 例如一个基本的枚举可能是

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

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

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

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

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

但是,你有一个编译器错误“重新定义枚举器”。 其实问题是编译器不确定你是第一次枚举,而第二个描述的是同一件事。

那么如果你想在几个地方重复使用相同的一组枚举器(这里是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;

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

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

你可以说在任何地方重写枚举都不方便,并且代码看起来有点奇怪。 你是对的。 真正的类型会更好。

这是我们进入峰会的最后一步。 通过添加一个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;
   ...
}

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

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

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

如果你正在使用XCode开发ObjectiveC,我让你发现一些以NS_ENUM为前缀的好宏。 这应该可以帮助您轻松定义好的枚举,此外还可以帮助静态分析器在编译之前为您做一些有趣的检查。

好的枚举!


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


typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;

那么你可以像这样使用它: -

 ShapeType shape;

 enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} 
ShapeType;

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

enum ShapeType shape;






typedef