【问题标题】:Is there a concise way to map a string to an enum in Objective-C?有没有一种简洁的方法可以将字符串映射到 Objective-C 中的枚举?
【发布时间】:2010-05-17 22:27:28
【问题描述】:

我有一个字符串要解析并返回一个等效的枚举。我需要在其他地方使用枚举类型,我想我喜欢我定义它的方式。问题是我不知道一个好方法可以根据枚举值检查字符串,而不会对枚举的顺序造成冗余。

除了大的 if/else 没有别的选择吗?

typedef enum {
    ZZColorRed,
    ZZColorGreen,
    ZZColorBlue,
} ZZColorType;


- (ZZColorType)parseColor:(NSString *)inputString {
    // inputString will be @"red", @"green", or @"blue" (trust me)
    // how can I turn that into ZZColorRed, etc. without
    // redefining their order like this?

    NSArray *colors = [NSArray arrayWithObjects:@"red", @"green", @"blue", nil];
    return [colors indexOfObject:inputString];
}

在 Python 中,我可能会执行以下操作,但老实说我也不喜欢它。

## maps  url text -> constant string
RED_CONSTANT = 1
BLUE_CONSTANT = 2
GREEN_CONSTANT = 3

TYPES = {
    'red': RED_CONSTANT,
    'green': GREEN_CONSTANT,
    'blue': BLUE_CONSTANT,
}

def parseColor(inputString):
    return TYPES.get(inputString)

ps。我知道 Cocoa 中有颜色常量,这只是一个例子。

【问题讨论】:

    标签: objective-c cocoa coding-style


    【解决方案1】:

    试试这个:Map enum to char array

    伪代码..未经测试。

    int lookup(const char* str) {
        for(name = one; name < NUMBER_OF_INPUTS; name++) {
            if(strcmp(str, stats[name]) == 0) return name;
        }
        return -1;
    }
    

    更客观的代码版本可能是:

    // build dictionary
    NSMutableDictionary* dict = [[NSMutableDictionary alloc] init];
    for(i=0; i<number_of_strings; i++) {
        [dict setObject:[NSNumber numberWithInteger:i] forKey:[NSString stringWithUTF8String:names[i]]];
    }
    
    // elsewhere... lookup in dictionary
    id obj = [dict objectForKey:name];
    if(obj) return [obj intValue];
    return -1;
    

    【讨论】:

    • 这还不错。我可以再添加一个枚举值 ZZColorMax,因此我不必对字符串数进行硬编码。
    【解决方案2】:

    这已经回答了:Converting between C enum and XML

    基本上,您在定义枚举时定义了相应的字符串,然后在NSArray 上使用一个类别,以便您可以这样做:

    static NSArray* colorNamesArray = [[NSArray alloc] initWithObjects:colorNames];
    //colorNames is a nil-terminated list of string literals #defined near your enum
    NSString* colorName = [colorNamesArray stringWithEnum:color];
    //stringWithEnum: is defined with a category
    

    当然,#define 有点难看,但上面的代码(大部分时间都会使用)实际上非常干净。

    【讨论】:

      【解决方案3】:

      我对任何建议都不满意。 (但我感谢他们付出的努力。)我尝试了其中的一些,但它们感觉不好或在实践中容易出错。

      我最终创建了一个自定义字典来将整数映射到字符串,这感觉好多了,因为它是彻头彻尾的 Cocoa。 (我没有继承 NSDictionary 以使其更难被滥用。)

      @interface ZZEnumDictionary : NSObject {
          NSMutableDictionary *dictionary;
      }
      
      + (id)dictionary;
      + (id)dictionaryWithStrings:(id)firstString, ...;
      - (NSString *)stringForInt:(NSInteger)intEnum;
      - (NSInteger)intForString:(NSString *)stringEnum;
      - (BOOL)isValidInt:(NSInteger)intEnum;
      - (BOOL)isValidString:(NSString *)stringEnum;
      - (BOOL)stringEquals:(NSString *)stringEnum intEnum:(NSInteger)intEnum;
      - (BOOL)setContainsString:(NSSet *)set forInt:(NSInteger)intEnum;
      - (NSArray *)allStrings;
      @end
      
      @interface ZZEnumDictionary ()
      - (void)setInt:(NSInteger)integer forString:(NSString *)string;
      @end
      

      【讨论】:

        猜你喜欢
        • 2010-09-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-06
        • 1970-01-01
        • 1970-01-01
        • 2021-11-09
        • 2019-01-29
        相关资源
        最近更新 更多