动态生成枚举参数?

时间:2013-01-01 01:10:11

标签: objective-c regex cocoa enums

我正在开发一个适用于Mac OS X应用程序的Cocoa,它为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。

我无法弄清楚这里适当的技术是什么。 选项参数采用带有按位OR运算符的整数,但是如何从这些复选框中的用户选择中动态构建它,所以我可以将它传递给该方法调用?

这是一个天真且不正确的尝试:

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

显然,选项不会使用NSString。但我希望这能澄清我正在做的事情让你理解这个问题!

2 个答案:

答案 0 :(得分:4)

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

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

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

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

答案 1 :(得分:1)

如果使用位的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)
你可以看到

他们有不同的目的。并且对差异的了解很重要。