如何在Objective-C中定义和使用ENUM?


180

我在实现文件中声明了一个枚举,如下所示,并在我的接口中将该类型的变量声明为PlayerState thePlayerState;并在我的方法中使用了变量。但是我收到错误消息指出它是未声明的。如何在我的方法中正确声明和使用PlayerState类型的变量?:

在.m文件中

@implementation View1Controller

    typedef enum playerStateTypes
        {
            PLAYER_OFF,
            PLAYER_PLAYING,
            PLAYER_PAUSED
        } PlayerState;

在.h文件中:

@interface View1Controller : UIViewController {

    PlayerState thePlayerState;

在.m文件中的某些方法中:

-(void)doSomethin{

thePlayerState = PLAYER_OFF;

}

2
现在枚举的类型是PlayerState。playerStateTypes变成什么?
user4951 2012年

3
有关NS_ENUM及其最新现代语法的信息,请参阅Mattt Thompson 发表的NS_ENUM和NS_OPTIONS
罗勒·布尔克

Answers:


109

typedef需要将其放在头文件(或其他已#import放入头文件中的文件)中,因为否则编译器将不知道生成PlayerStateivar的大小。除此之外,我觉得还可以。


在我看来,将其放在单独文件中的选项似乎是正确的。我不知道这是否是一个好方法,但是我需要在两个不同的ViewControllers中使用相同的枚举(自身以及它的委托/数据源)。导入委托/数据源的标头会导致错误,对于简单的需求来说似乎太多了。因此,我用声明的枚举创建了一个新的.h文件,并将其导入到两个viewControllers.h文件中。像魅力一样工作。
Leandro Alves

7
应该建议使用NS_ENUM宏-因为这是最佳做法
khebbie 2013年

1
NS_ENUM如果希望枚举在Swift代码中可用,则必须在Objective-C中使用声明枚举。
smileyborg

@DaveDeLong,这在2015年仍然有效吗?我typedef.m文件中声明了它,并且可以编译并运行良好。
Iulian Onofrei 2015年

@IulianOnofrei如果需要在其他文件中使用枚举,它将放在.h文件中。如果只需要将其放在一个文件中,则将其放到.m文件中总是很好。
Dave DeLong

206

Apple提供了一个宏来帮助提供更好的代码兼容性,包括Swift。使用宏看起来像这样。

typedef NS_ENUM(NSInteger, PlayerStateType) {
  PlayerStateOff,
  PlayerStatePlaying,
  PlayerStatePaused
};

记录在这里


Obj C枚举是否可以像Java中那样具有成员变量?如果是这样,怎么办?
Clocksmith

那么第二种解决方案更好?
Iulian Onofrei 2014年

3
第二种解决方案更好(使用NS_ENUM),因为它更现代,如果希望枚举可在Swift代码中使用,Objective-C现在需要它。
smileyborg 2015年

更新以显示第二个解决方案实际上更好。
rebelzach

在Apple的标准格式中,每个枚举值都重复类型名称。
ThomasW

29

在.h中:

typedef enum {
    PlayerStateOff,
    PlayerStatePlaying,
    PlayerStatePaused
} PlayerState;

1
您可以在其他SO问题中找到类似的答案,但是当我查看枚举时,该问题首先弹出,因此我也在此处添加了答案。
Ben Flynn

19

对于当前项目,您可能需要使用NS_ENUM()NS_OPTIONS()宏。

typedef NS_ENUM(NSUInteger, PlayerState) {
        PLAYER_OFF,
        PLAYER_PLAYING,
        PLAYER_PAUSED
    };

2
...而且现在更重要的是,NS_ENUM如果希望枚举在Swift代码中可用,则必须在Objective-C中使用声明枚举。
smileyborg

16

这是Apple对类似NSString这样的类的处理方式:

在头文件中:

enum {
    PlayerStateOff,
    PlayerStatePlaying,
    PlayerStatePaused
};

typedef NSInteger PlayerState;

请参阅http://developer.apple.com/上的编码准则


3
这实际上对OP没有帮助。尽管从技术上讲是正确的,但并没有告诉他们如何创建可重用的枚举
RyanR 2011年

24
链接到developer.apple.com并没有真正的帮助。您还有其他地方要引用吗?
布雷特

复制/粘贴已经提供的文档,主页上的链接确实对其他人没有帮助...
Onder OZCAN 2015年


8

我建议使用NS_OPTIONS或NS_ENUM。您可以在此处了解更多信息:http : //nshipster.com/ns_enum-ns_options/

这是我使用NS_OPTIONS编写的代码的示例,我有一个实用程序,可在UIView的图层上设置子图层(CALayer)以创建边框。

h。文件:

typedef NS_OPTIONS(NSUInteger, BSTCMBorder) {
    BSTCMBOrderNoBorder     = 0,
    BSTCMBorderTop          = 1 << 0,
    BSTCMBorderRight        = 1 << 1,
    BSTCMBorderBottom       = 1 << 2,
    BSTCMBOrderLeft         = 1 << 3
};

@interface BSTCMBorderUtility : NSObject

+ (void)setBorderOnView:(UIView *)view
                 border:(BSTCMBorder)border
                  width:(CGFloat)width
                  color:(UIColor *)color;

@end

.m文件:

@implementation BSTCMBorderUtility

+ (void)setBorderOnView:(UIView *)view
                 border:(BSTCMBorder)border
                  width:(CGFloat)width
                  color:(UIColor *)color
{

    // Make a left border on the view
    if (border & BSTCMBOrderLeft) {

    }

    // Make a right border on the view
    if (border & BSTCMBorderRight) {

    }

    // Etc

}

@end
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.