2010-05-17 2 views
0

J'ai une chaîne que je veux analyser et retourner une énumération équivalente. J'ai besoin d'utiliser le type enum ailleurs, et je pense que j'aime comment je le définis. Le problème est que je ne connais pas un bon moyen de vérifier la chaîne par rapport aux valeurs enum sans être redondant sur l'ordre des énumérations.Existe-t-il un moyen concis de mapper une chaîne à une énumération en Objective-C?

N'y a-t-il pas d'autre option qu'un gros if/else? En Python, je ferais probablement quelque chose comme ce qui suit, bien que pour être honnête, je ne suis pas non plus amoureux de ça.

## 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. Je sais qu'il y a des constantes de couleur dans Cocoa, ce n'est qu'un exemple.

Répondre

0

Je n'ai jamais été satisfait de l'une des suggestions. (Mais j'apprécie l'effort qui leur a été fourni.) J'en ai essayé quelques-uns, mais ils ne se sentaient pas bien ou étaient enclins aux erreurs en pratique.

J'ai fini par créer un dictionnaire personnalisé pour mapper des entiers à des chaînes de caractères qui se sent beaucoup mieux parce que c'est Cocoa à travers et à travers. (Je n'ai pas sous-classé NSDictionary afin de rendre plus difficile à abuser.)

@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 
3

essayez ceci: Map enum to char array

Pseudo Code .. non testé.

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

Un objectif plus-c'ish version du code pourrait être:

// 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; 
+0

Ce n'est pas si grave. Je peux virer sur une valeur enum plus ZZColorMax donc je n'ai pas besoin de coder en dur le nombre de chaînes. – zekel

+1

+1 le dictionnaire est probablement la meilleure façon de faire. –

0

Cela a déjà été répondu: Converting between C enum and XML

Fondamentalement, vous liquidez définir des chaînes correspondantes lorsque vous définissez votre énumération, puis vous utilisez une catégorie sur NSArray afin que vous puissiez le faire:

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 

Bien sûr, le #define est un peu moche, mais le code ci-dessus, qui est ce que vous allez travailler avec la plupart du temps, est en fait assez propre.

Questions connexes