【问题标题】:How do I define and use an ENUM in Objective-C?如何在 Objective-C 中定义和使用 ENUM?
【发布时间】:2011-01-13 19:13:36
【问题描述】:

我在我的实现文件中声明了一个枚举,如下所示,并在我的接口中声明了一个该类型的变量作为 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;

}

【问题讨论】:

  • 现在枚举的类型是 thePlayerState。 playerStateTypes 变成了什么?
  • 有关 NS_ENUM 及其最新现代语法的信息,请参阅 Mattt Thompson 的帖子NS_ENUM & NS_OPTIONS

标签: iphone objective-c c


【解决方案1】:

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

【讨论】:

  • 在我的情况下,将其放在单独的文件中的选项似乎是正确的。我不知道这是否是一个好方法,但我需要在两个不同的 ViewController(self 和它的委托/数据源)中使用相同的枚举。导入委托/数据源的标头会导致错误,对于简单的需求来说似乎太多了。因此,我创建了一个新的 .h 文件,其中声明了枚举并将其导入到两个 viewControllers.h 文件中。像魅力一样工作。
  • 应该推荐使用 NS_ENUM 宏——因为这是最佳实践
  • 如果你想让你的枚举在 Swift 代码中可用,你必须在 Objective-C 中使用 NS_ENUM 声明枚举。
  • @DaveDeLong,这在 2015 年仍然有效吗?我在.m 文件中声明了typedef,它编译并运行良好。
  • @IulianOnofrei 如果您需要在其他文件中使用枚举,它将进入 .h 文件。如果你只需要在一个文件中,把它放在 .m 文件中一直都很好。
【解决方案2】:

这就是 Apple 对 NSString 等类的处理方式:

在头文件中:

enum {
    PlayerStateOff,
    PlayerStatePlaying,
    PlayerStatePaused
};

typedef NSInteger PlayerState;

请参阅 http://developer.apple.com/ 的编码指南

【讨论】:

  • 这实际上对 OP 没有帮助。虽然在技术上是正确的,但它并没有告诉他们如何创建可重用的枚举
  • 链接到 developer.apple.com 并没有真正的帮助。您还想引用其他地方吗?
  • 复制/粘贴已经给出的文档,作为主页的链接真的对其他人没有帮助......
  • 这已经过时了,请看这个页面developer.apple.com/library/ios/releasenotes/ObjectiveC/…
【解决方案3】:

在.h中:

typedef enum {
    PlayerStateOff,
    PlayerStatePlaying,
    PlayerStatePaused
} PlayerState;

【讨论】:

  • 你可以在其他SO问题中找到这样的答案,但是我在查看枚举时,首先弹出了这个问题,所以我在这里也添加了答案。
【解决方案4】:

Apple 提供了一个宏来帮助提供更好的代码兼容性,包括 Swift。使用宏如下所示。

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

Documented here

【讨论】:

  • Obj C 枚举可以像在 Java 中那样拥有成员变量吗?如果有,怎么做?
  • 那么第二种方案更好?
  • 第二种解决方案更好(使用NS_ENUM),因为它更现代,如果您希望枚举在 Swift 代码中可用,现在在 Objective-C 中是必需的。
  • 更新显示第二种解决方案实际上更好。
  • 在 Apple 的标准形式中,每个枚举值都会重复类型名称。
【解决方案5】:

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

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

【讨论】:

  • ...更重要的是,如果您希望枚举在 Swift 代码中可用,则必须在 Objective-C 中使用 NS_ENUM 声明枚举。
【解决方案6】:

我建议使用 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-07
    • 1970-01-01
    • 2019-12-25
    • 2010-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-10
    相关资源
    最近更新 更多