2009-06-18 18 views
17

¿Las enumeraciones no están permitidas como claves para un NSMutableDictionary?typedef enum escriba como clave para NSDictionary?

Cuando trato de añadir al diccionario a través de:

[self.allControllers setObject:aController forKey:myKeyType]; 

me sale el error:

error: incompatible type for argument 2 of 'setObject:forKey:'

Por lo general, utilizo NSString como mi nombre de clave que no requiere un yeso para 'id' pero para hacer desaparecer el error, tuve que hacer eso. ¿El casting es el comportamiento correcto aquí o las enumeraciones son una mala idea?

Mi enumeración se define como:

typedef enum tagMyKeyType 
{ 
    firstItemType = 1, 
    secondItemType = 2 
} MyKeyType; 

y el diccionario se define y se asigna adecuadamente como tal:

NSMutableDictionary *allControllers; 

allControllers = [[NSMutableDictionary alloc] init]; 
+0

¿por qué no utiliza una matriz? – user102008

Respuesta

21

Puede almacenar la enumeración en un NSNumber sin embargo. (¿No son las enumeraciones solo las entradas?)

[allControllers setObject:aController forKey:[NSNumber numberWithInt: firstItemType]]; 

En Cocoa, const NSStrings se utilizan a menudo. En el .h le declarar algo como:

NSString * const kMyTagFirstItemType; 
NSString * const kMyTagSecondtItemType; 

Y en el archivo .m que pondría

NSString * const kMyTagFirstItemType = @"kMyTagFirstItemType"; 
NSString * const kMyTagSecondtItemType = @"kMyTagSecondtItemType"; 

A continuación, se puede utilizar como una clave en un diccionario.

[allControllers setObject:aController forKey:kMyTagFirstItemType]; 
+2

Creo que quieres usar la palabra clave 'extern' en el archivo .h aquí, ¿correcto? –

+0

También puede usar 'FOUNDATION_EXPORT' como la palabra clave que creo que también está tipdef'd to' extern'. –

3

No, no se puede. Mire la firma del método: id especifica un objeto. Un tipo enum es un escalar. No puedes transmitir de uno a otro y esperar que funcione correctamente. Tienes que usar un objeto.

+5

Esto es cierto. Sin embargo, puede ajustar el valor enum en un NSNumber y usarlo como la clave. – LBushkin

4

Esta es una pregunta anterior, pero se puede actualizar para utilizar una sintaxis más moderna. En primer lugar, a partir de iOS 6, Apple recomienda que las enumeraciones se definen como:

typedef NS_ENUM(NSInteger, MyEnum) { 
    MyEnumValue1 = -1, // default is 0 
    MyEnumValue2, // = 0 Because the last value is -1, this auto-increments to 0 
    MyEnumValue3 // which means, this is 1 
}; 

Entonces, ya que tenemos la enumeración representado como NSInteger s internamente, podemos encajonarlos en NSNumber s para almacenar como la clave para un diccionario .

NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; 

// set the value 
dictionary[@(MyEnumValue1)] = @"test"; 

// retrieve the value 
NSString *value = dictionary[@(MyEnumValue1)]; 

EDIT: Cómo crear un diccionario Singleton para este fin

A través de este método, se puede crear un diccionario Singleton para ayudar con esto. En la parte superior de cualquier archivo que tenga, puede utilizar:

static NSDictionary *enumTranslations; 

Luego, en su init o viewDidLoad (si está haciendo esto en un controlador de interfaz de usuario), se puede hacer esto:

static dispatch_once_t onceToken; 
// this, in combination with the token above, 
// will ensure that the block is only invoked once 
dispatch_async(&onceToken, ^{ 
    enumTranslations = @{ 
     @(MyEnumValue1): @"test1", 
     @(MyEnumValue2): @"test2" 
     // and so on 
    }; 
}); 




// alternatively, you can do this as well 
static dispatch_once_t onceToken; 
// this, in combination with the token above, 
// will ensure that the block is only invoked once 
dispatch_async(&onceToken, ^{ 
    NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary]; 
    mutableDict[@(MyEnumValue1)] = @"test1"; 
    mutableDict[@(MyEnumValue2)] = @"test2"; 
    // and so on 

    enumTranslations = mutableDict; 
}); 

Si desea que este diccionario sea visible externamente, mueva la declaración estática a su archivo de encabezado (.h).