【问题标题】:Generate an enum argument dynamically?动态生成枚举参数?
【发布时间】:2013-01-01 01:10:11
【问题描述】:

我正在开发一个 Cocoa for Mac OS X 应用程序,它为 NSRegularExpression 搜索提供了一系列选项。这些选项表示为这样的枚举:

enum {
NSRegularExpressionCaseInsensitive             = 1 << 0,
NSRegularExpressionAllowCommentsAndWhitespace  = 1 << 1,
NSRegularExpressionIgnoreMetacharacters        = 1 << 2,
NSRegularExpressionDotMatchesLineSeparators    = 1 << 3,
NSRegularExpressionAnchorsMatchLines           = 1 << 4,
NSRegularExpressionUseUnixLineSeparators       = 1 << 5,
NSRegularExpressionUseUnicodeWordBoundaries    = 1 << 6
};
typedef NSUInteger NSRegularExpressionOptions;

我想让用户从这些选项中的任何一个中进行选择(这是一系列复选框),然后将结果传递给方法 regularExpressionWithPattern:options:error:。我将这些选项作为整数接收,因此用户可能会选择 0 和 5,例如。

我无法弄清楚这里的正确技术是什么。 options 参数采用按位 OR 运算符的整数,但是如何根据用户在这些复选框中的选择动态构建它,以便将其传递给该方法调用?

这是一个幼稚且不正确的尝试:

for (NSButtonCell * cell in [sender selectedCells]) {
    NSNumber * tag = [NSNumber numberWithInteger:[cell tag] - 1];
    [self.optionsString stringByAppendingString:[NSString stringWithFormat:@"%@|", [tag stringValue]]];
}

显然,options 不采用 NSString。但我希望这能澄清我在做什么,以便您理解这个问题!

【问题讨论】:

    标签: objective-c regex cocoa enums


    【解决方案1】:

    您只需要按位或选择的选项。 |= 运算符让您可以简洁地执行此操作。

    如果您的单元格标记为 0 到 6:

    NSUInteger options = 0;
    for (NSButtonCell * cell in [sender selectedCells])
        options |= (1 << [cell tag]);
    

    我不太明白您为什么要在示例代码中从 [cell tag] 中减去一个。

    【讨论】:

    • 懒惰:我标记了从 1 开始的选项。:-)
    • 方便的是,有一个|= 运算符,可以在表达式中为您节省一个单词options 的实例。
    【解决方案2】:

    如果您使用位的 int 值。 (即 1、2、4、8.. 等)

    您可以将它们按原样用于 True 选择。

    NSRegularExpressionOptions selectedOptions = 0;
    for (NSButtonCell * cell in [sender selectedCells]) {
        selectedOptions = selectedOptions | tag.unsignedIntegerValue;
    }
    

    因为这些值是标志,您可以使用按位或 (|) 来生成任何一个值中的任何标志。

    请务必将标签设置为您要使用的 int 值。 (即 1、2、4、8、16、32 和 64)

    或者你可以把它们加起来。

    它们的位值如下。

    enum {
        NSRegularExpressionCaseInsensitive             = 1 << 0,
        NSRegularExpressionAllowCommentsAndWhitespace  = 1 << 1,
        NSRegularExpressionIgnoreMetacharacters        = 1 << 2,
        NSRegularExpressionDotMatchesLineSeparators    = 1 << 3,
        NSRegularExpressionAnchorsMatchLines           = 1 << 4,
        NSRegularExpressionUseUnixLineSeparators       = 1 << 5,
        NSRegularExpressionUseUnicodeWordBoundaries    = 1 << 6
    };
    
        NSRegularExpressionCaseInsensitive             == 0b00000001; // (1)
        NSRegularExpressionAllowCommentsAndWhitespace  == 0b00000010; // (2)
        NSRegularExpressionIgnoreMetacharacters        == 0b00000100; // (4)
        NSRegularExpressionDotMatchesLineSeparators    == 0b00001000; // (8)
        NSRegularExpressionAnchorsMatchLines           == 0b00010000; // (16)
        NSRegularExpressionUseUnixLineSeparators       == 0b00100000; // (32)
        NSRegularExpressionUseUnicodeWordBoundaries    == 0b01000000; // (64)
    

    它们的值通过“按位或(|)”以及加法等价

        Via Addition            NSUInteger value = 2 + 4;
        or bitwise or ( | )     NSUInteger value = 2 | 4;
        Even with Bitshifting   NSUInteger value = (1 << 1) + (1 << 2);
                                NSUInteger value = (1 << 1) | (1 << 2);
    
         0b00000010   (2)
        +0b00000100  +(4)
        -----------   ---
         0b00000110   (6)
    

    按位或派上用场的地方是打开标志。

           (addition)
         0b00000010   (2)
        +0b00000110  +(6)
        -----------   ---
         0b00001000   (8)
    
    
    
           (bitwise or)
         0b00000010   (2)
        |0b00000110  |(6)
        -----------   ---
         0b00000110   (6)
    

    因为或仅在“Both”值中打开标志。你会得到和开始一样的东西。

    一个更复杂的例子是这个。

           (bitwise or)
         0b00010010   (18)
        |0b00000110  |(6)
        -----------   ---
         0b00010110   (22)
    
    
           (addition)
         0b00010010   (18)
        +0b00000110  +(6)
        -----------   ---
         0b00011000   (24)
    

    如您所见。他们有不同的目的。并且了解差异很重要。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-06-02
      • 1970-01-01
      • 2011-10-01
      • 1970-01-01
      • 2012-04-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多