乐趣区

iOS开发中定义枚举的正确姿势NSENUM-VS-enum

iOS 开发中 枚举 也是经常会用到的数据类型之一。最近在整理别人写的老项目的时候,发现枚举的定义使用了多种方式。

  • 方式 1
typedef enum {
    MJPropertyKeyTypeDictionary = 0, // 字典的 key
    MJPropertyKeyTypeArray // 数组的 key
} MJPropertyKeyType;
  • 方式 2
typedef enum: NSInteger {
        None,
        Melee,
        Fire,
        Ice,
        Posion
    }AttackType;
  • 方式 3
typedef NS_ENUM(NSUInteger, MeiziCategory) {
    MeiziCategoryAll = 0,
    MeiziCategoryDaXiong,
    MeiziCategoryQiaoTun,
    MeiziCategoryHeisi,
    MeiziCategoryMeiTui,
    MeiziCategoryQingXin,
    MeiziCategoryZaHui
};
  • 方式 4

这种比较特殊 支持位操作

typedef NS_OPTIONS(NSUInteger, ActionType) {
    ActionTypeUp    = 1 << 0, // 1
    ActionTypeDown  = 1 << 1, // 2
    ActionTypeRight = 1 << 2, // 4
    ActionTypeLeft  = 1 << 3, // 8
};

针对于前三种方式,我们应该使用那一种更新好呢?
这是来自 Stack Overflow 的解释。

First, NS_ENUM uses a new feature of the C language where you can specify the underlying type for an enum. In this case, the underlying type for the enum is NSInteger (in plain C it would be whatever the compiler decides, char, short, or even a 24 bit integer if the compiler feels like it).

Second, the compiler specifically recognises the NS_ENUM macro, so it knows that you have an enum with values that shouldn’t be combined like flags, the debugger knows what’s going on, and the enum can be translated to Swift automatically.

翻译:

首先,NS_ENUM 使用 C 语言的一个新特性,您可以在该特性中指定 enum 的底层类型。在本例中,enum 的底层类型是 NSInteger(在普通的 C 语言中,它是编译器决定的任何类型,char、short,甚至是编译器喜欢的 24 位整数)。

其次,编译器专门识别 NS_ENUM 宏,因此它知道您有一个 enum,它的值不应该像标志那样组合在一起,调试器知道发生了什么,并且 enum 可以自动转换为 Swift。

从解释可以看出,定义普通的枚举时,推荐我们使用第三种方式 NS_ENUM(), 定义位移相关的枚举时,我们则使用 NS_OPTIONS()

而且我们查看苹果的框架,发现苹果使用的也是第三种和第四种。苹果的官方文档也有明确的说明,推荐我们使用NS_ENUM()NS_OPTIONS()

总结:结合 Stack Overflow 和苹果官方的说明,我们以后在定义枚举时,应该使用NS_ENUM()NS_OPTIONS(),这样更规范。

退出移动版