¿Cómo defino y uso un ENUM en Objective-C?

180

Declaré una enumeración en mi archivo de implementación como se muestra a continuación, y declaró una variable de ese tipo en mi interfaz como PlayerState thePlayerState; y usé la variable en mis métodos. Pero recibo errores que indican que no está declarado. ¿Cómo declaro y uso correctamente una variable de tipo PlayerState en mis métodos ?:

En el archivo .m

@implementation View1Controller

    typedef enum playerStateTypes
        {
            PLAYER_OFF,
            PLAYER_PLAYING,
            PLAYER_PAUSED
        } PlayerState;

en el archivo .h:

@interface View1Controller : UIViewController {

    PlayerState thePlayerState;

en algún método en el archivo .m:

-(void)doSomethin{

thePlayerState = PLAYER_OFF;

}
RexOnRoids
fuente
2
Ahora el tipo de la enumeración es thePlayerState. ¿En qué se convierte playerStateTypes?
user4951
3
Para obtener información sobre NS_ENUM y su sintaxis moderna más reciente, consulte la publicación NS_ENUM & NS_OPTIONS por Mattt Thompson.
Basil Bourque

Respuestas:

109

Sus typedefnecesidades para estar en el archivo de cabecera (o algún otro archivo que se #imported en su cabecera), porque de lo contrario el compilador no sabrá qué tamaño para hacer el PlayerStateIvar. Aparte de eso, me parece bien.

Dave DeLong
fuente
La opción de ponerlo en un archivo separado parecía correcta en mi caso. No sé si este es un buen enfoque, pero necesitaba usar la misma enumeración en dos ViewControllers diferentes (self y delegate / datasource). Importar el encabezado del delegado / fuente de datos resultó en un error y parece demasiado para una simple necesidad. Así que creé un nuevo archivo .h con la enumeración declarada y lo importé en ambos archivos viewControllers.h. Trabajado como un encanto.
Leandro Alves
77
Debe recomendar a utilizar la macro NS_ENUM - ya que esta es la mejor práctica
khebbie
1
Debe declarar enumeraciones utilizando NS_ENUMObjective-C si desea que su enumeración esté disponible en código Swift.
smileyborg
@DaveDeLong, ¿sigue siendo válido en 2015? Tengo el typedefdeclarado en el .marchivo y se compila y funciona bien.
Iulian Onofrei
@IulianOnofrei iría en el archivo .h si necesita usar la enumeración en otros archivos. Si solo lo necesita en un archivo, ponerlo en el archivo .m siempre ha estado perfectamente bien.
Dave DeLong
206

Apple proporciona una macro para ayudar a proporcionar una mejor compatibilidad de código, incluido Swift. Usar la macro se ve así.

typedef NS_ENUM(NSInteger, PlayerStateType) {
  PlayerStateOff,
  PlayerStatePlaying,
  PlayerStatePaused
};

Documentado aquí

rebelzach
fuente
¿Las Obj C Enums pueden tener variables miembro como pueden en Java? ¿Si es así, cómo?
Relojero
Entonces, ¿la segunda solución es mejor?
Iulian Onofrei
3
La segunda solución es mejor (usar NS_ENUM), ya que es más moderna y ahora se requiere en Objective-C si desea que su enumeración esté disponible en el código Swift.
smileyborg
Actualizado para mostrar que la segunda solución es, de hecho, mejor.
rebelzach
En la forma estándar de Apple, el nombre del tipo se repite para cada valor de enumeración.
ThomasW
29

En el .h:

typedef enum {
    PlayerStateOff,
    PlayerStatePlaying,
    PlayerStatePaused
} PlayerState;
Ben Flynn
fuente
1
Puede encontrar una respuesta como esta en otras preguntas SO, pero cuando estaba revisando enumeraciones, esta pregunta apareció primero, así que agregué la respuesta aquí también.
Ben Flynn
19

Con los proyectos actuales es posible que desee utilizar las macros NS_ENUM()o NS_OPTIONS().

typedef NS_ENUM(NSUInteger, PlayerState) {
        PLAYER_OFF,
        PLAYER_PLAYING,
        PLAYER_PAUSED
    };
Sean Woodward
fuente
2
... y lo más importante ahora, debe declarar enumeraciones usando NS_ENUMObjective-C si desea que su enumeración esté disponible en el código Swift.
smileyborg
16

Así es como Apple lo hace para clases como NSString:

En el archivo de encabezado:

enum {
    PlayerStateOff,
    PlayerStatePlaying,
    PlayerStatePaused
};

typedef NSInteger PlayerState;

Consulte las Pautas de codificación en http://developer.apple.com/

Santhos
fuente
3
Esto en realidad no ayuda al OP. Aunque técnicamente es correcto, no les dice cómo crear una enumeración reutilizable
RyanR
24
Vincular a developer.apple.com no es realmente útil. ¿Hay algún otro lugar que te gustaría citar?
Brett
Copie / pegue la documentación que ya ha proporcionado, el enlace que es la página principal realmente no está ayudando a otras personas ...
Onder OZCAN
3
Esto está desactualizado, vea esta página developer.apple.com/library/ios/releasenotes/ObjectiveC/…
Alex Chesters
8

Recomiendo usar NS_OPTIONS o NS_ENUM. Puede leer más sobre esto aquí: http://nshipster.com/ns_enum-ns_options/

Aquí hay un ejemplo de mi propio código usando NS_OPTIONS, tengo una utilidad que establece una subcapa (CALayer) en una capa de UIView para crear un borde.

El h. expediente:

typedef NS_OPTIONS(NSUInteger, BSTCMBorder) {
    BSTCMBOrderNoBorder     = 0,
    BSTCMBorderTop          = 1 << 0,
    BSTCMBorderRight        = 1 << 1,
    BSTCMBorderBottom       = 1 << 2,
    BSTCMBOrderLeft         = 1 << 3
};

@interface BSTCMBorderUtility : NSObject

+ (void)setBorderOnView:(UIView *)view
                 border:(BSTCMBorder)border
                  width:(CGFloat)width
                  color:(UIColor *)color;

@end

El archivo .m:

@implementation BSTCMBorderUtility

+ (void)setBorderOnView:(UIView *)view
                 border:(BSTCMBorder)border
                  width:(CGFloat)width
                  color:(UIColor *)color
{

    // Make a left border on the view
    if (border & BSTCMBOrderLeft) {

    }

    // Make a right border on the view
    if (border & BSTCMBorderRight) {

    }

    // Etc

}

@end
Johannes
fuente