【问题标题】:NS_OPTIONS Bitmask AutogenerationNS_OPTIONS 位掩码自动生成
【发布时间】:2013-06-18 18:31:27
【问题描述】:

我有一个很大的枚举(为了透明起见 63 个值),我现在正在基于该枚​​举创建一个 NS_Options 位标志。有没有一种方法可以让我编写它以使其灵活?

我对硬编码的主要担忧是:

  • 如果我添加/删除一个枚举,我将不得不在我的 bitflag 中手动添加/删除它。
  • 需要大量输入才能生成这些内容。
  • 我的 .h 文件变得非常长(因为我喜欢使用空格和足够的 cmets)

到目前为止,我想出的唯一解决方案是:

#define FlagForEnum(enum) 1 << enum

typedef NS_ENUM(NSInteger, ExampleEnum)
{
    Value1,
    Value2,
    ...
    ValueN
}

typedef NS_OPTIONS(NSNumber, ExampleEnumFlags)
{
    Value1Flag = FlagForEnum(Value1),
    Value2Flag = FlagForEnum(Value2),
    ...
    ValueNFlag = FlagForEnum(ValueN)
}

当我删除一个枚举(至少我得到一个编译错误)时,这是一个勉强足够的解决方案,如果枚举顺序发生变化,标志的位移位置也会发生变化(这并不重要,但它似乎令人欣慰)。但它并不能解决“大量输入”的问题,或者“如果我忘记添加标志会怎样”的问题。

【问题讨论】:

  • 不是你的问题的答案,但 Go 有一个巧妙的方法:golang.org/ref/spec#Iota
  • 您对一些代码生成(例如快速 Python 脚本)有何感想?
  • @JoshBleecherSnyder 代码生成似乎是合理的;绝对比我的预处理器代码更可重用。

标签: ios objective-c enums bitflags


【解决方案1】:

你可以使用一种叫做X Macro的技术

#define VALUES \
  VALUE_LINE(Value1) \
  VALUE_LINE(Value2) \
  VALUE_LINE(Value3)

typedef NS_ENUM(NSUInteger, ExampleEnum)
{
#define VALUE_LINE(x) x,
VALUES
#undef VALUE_LINE
}

typedef NS_OPTIONS(NSUInteger, ExampleEnumFlags)
{
#define VALUE_LINE(x) x##Flag = 1 << x,
VALUES
#undef VALUE_LINE
}

【讨论】:

    【解决方案2】:

    这里有一个稍微好一点的(就减少打字而言)预处理器#define 解决方案。虽然这仍然没有我想要的那么优雅。

    #define BitShift(ENUM_ATTRIBUTE)            (1 << ENUM_ATTRIBUTE)
    #define CreateEnumFlag(ENUM_ATTRIBUTE)      ENUM_ATTRIBUTE##Flag = BitShift(ENUM_ATTRIBUTE)
    
    typedef NS_ENUM(NSUInteger, ExampleEnum)
    {
        Value1,
        Value2,
        ...
        ValueN
    }
    
    typedef NS_Options(NSUInteger, ExampleEnumFlags)
    {
        CreateEnumFlag(Value1),
        CreateEnumFlag(Value2),
        ...
        CreateEnumFlag(ValueN)
    }
    

    这将创建Value1FlagValue2Flag、...、ValueNFlag 形式的标志。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-28
      • 2010-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多