2009-06-10 6 views
13

Soy nuevo en Obj-C así que discúlpeme si esta es una pregunta estúpida:Clases de estilo Java-enum en Objective-C?

¿Cómo puedo implementar algunas al estilo de las enums de Javas? O para ser más precisos:

Quiero una clase con algunas propiedades conocidas que son correctas en tiempo de compilación y únicas por instancia. Además, solo quiero un tipo de instancia.

te voy a dar un ejemplo en Java:

public enum MessageTypes { 
    DEFAULT("white", "standard", 1), 
    EXPRESS("red", "expressMessage", 2), 
    BORADCAST("green", "broadcast", 3); 

    String color; String tagName; int dbId; 
    MessageTypes(String color, String tagName, int dbId) { 
    // you get the idea 
    } 
    //some methonds like getEnumByTagName 
} 

¿Cómo hacer algo como esto en Objective-C? ¿Me estoy perdiendo de algo? ¿Es este un mal patrón en absoluto?

¡Gracias de antemano!

EDITAR: Lo siento, si no me aclaro. Sé que las enumeraciones obj-cc no son lo que estoy buscando (ya que solo son marginalmente más que un typedef a un int).

Me gustaría crear un conjunto de instancias (kind-of-singleton, inmutable) de una clase específica. El patrón singleton en Apples Dev-Docs no sirve, ya que quiero múltiples instancias distintas de una clase, cada una con valores individuales en sus propiedades.

El objetivo de esto es tener varios tipos de mensajes (alrededor de 20) que se pueden asignar a un mensaje como una propiedad. Cada uno de mis tipos de mensajes tiene un color (fijo y predefinido), valor de atributo (en una representación XML) y una identificación numérica.

En Java, usaría una enumeración como en mi ejemplo de código. ¿Pero cómo creo diferentes MessageTypes y los asoció con sus propiedades en Obj-C?

Crear 20 subcategorías de MessageType (cada una con una instancia de singleton que contiene las propiedades) parece mucho trabajo para una tarea tan simple y una exageración total.

Mi enfoque actual es crear una clase con un NSArray que contenga las diferentes instancias. En el primer acceso de un método como +(id)messageTypeForId:NSInteger id_, el NSArray está prepoblado. Pero esto se siente totalmente torpe y para nada elegante ...

¿Hay un enfoque más satisfactorio?

Respuesta

7

No hay mucho en el camino de un "enfoque más satisfactorio".

El patrón de cacao normal, sería la creación de métodos como:

+ (MessageTypes*) sharedDefaultMessageType; 
+ (MessageTypes*) sharedExpressMessageType; 
+ (MessageTypes*) sharedBroadcastMessageType; 
etc 

y luego poner en práctica algo así como:

+ (MessageTypes*) sharedDefaultMessageType 
{ 
    static MessageTypes* thisMessageType = nil; 
    if (!thisMessageType) { 
     thisMessageType = [[MessageTypes alloc] initWithColor:@"white" tagName:@"standard" dbId:1]; 
    } 
    return thisMessageType; 
} 

Alternativamente, el almacenamiento de la MessageType compartida * en un NSMutableArray o NSMutableDictionary o puede calcular previamente ellos como lo están haciendo son todos accesos igualmente válidos.

Tenga en cuenta que el método de "plantilla" por encima podría generarse a través de una macro de tal manera que se puede escribir en el archivo .m:

CREATEMESSAGETYPE(Default, @"white", @"standard", 1) 
CREATEMESSAGETYPE(Express, @"red", @"expressMessage", 2) 
CREATEMESSAGETYPE(Broadcast, @"green", @"broadcast", 3) 

la que podría ser "más satisfactorio" o más feo, dependiendo de su punto de vista.

+0

El macro es más feo en mi punto de vista, pero realmente me gusta su primera solución. Eso parece ser mejor (y más parecido al cacao) que mi enfoque. Gracias. –

+0

Veo cómo 'convencionalmente' y 'compartido' son utilizados por la convención en algunas clases, ¿hay otros prefijos como esos? – zekel

+0

En su primera solución, ¿por qué comprueba si thisMessageType es nulo antes de llamar a alloc? ¿No será siempre nulo debido a la línea que lo precede? Thx por ayudar a un novato. –

1

Creo que sólo haría uso de una enumeración estándar de C:

typedef enum { MT_WHITE, MT_RED, MT_GREEN } MessageType; 

A continuación, sólo lo utilizan como lo haría con cualquier otro tipo de datos:

@interface Blah {} 

-(void) setMessageType:(MessageType)newMessageType; 

@end 
+4

Bueno, entonces no obtengo mis propiedades, que son únicas por instancia. –

0

enumeraciones no son objetos en C, y, por lo tanto, tampoco en el Objetivo-C. Solo son escalares definidos por el usuario que tienen un conjunto limitado de valores con nombre que pueden tomar. Puede otorgarle a un objeto propiedades que son tipos enum, que creo que están más cerca de lo que está buscando.

Si hay algo específico que necesita lograr con esta funcionalidad, es posible que desee editar su publicación para indicar lo que es.

0

Tuve la misma pregunta más o menos pero encuentro todas las soluciones anteriores torpemente estilísticas. En particular, cuando simplemente se utiliza una propiedad C enum en un objeto, se pierde la semántica singleton de las enumeraciones Java. La mayor libertad que he encontrado en el uso de las enumeraciones de Java es que las instancias de una enumeración son realmente subclases de singleton, por lo que participan en el polimorfismo de métodos. Incluso más poderoso que las enumeraciones con atributos únicos es enumeraciones con comportamiento polimórfico.

Dado que esta es la característica clave que estoy buscando, ¿sería un clúster de clase Objective-C con subclases individuales singleton un enfoque con el comportamiento deseado, a pesar de ser un poco excesivo en complejidad y costo de implementación?

Cuestiones relacionadas