¿Qué es una enumeración typedef en Objective-C?

Creo que no entiendo fundamentalmente qué enum es y cuándo usarlo.

Por ejemplo:

typedef enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} ShapeType;

¿Qué se está declarando realmente aquí?

preguntado el 01 de abril de 09 a las 18:04

¿El tipo definido por el usuario se llama "enum"? Eso es lo que había pensado, hasta que encontré un código que tenía varias declaraciones de enumeración typedef. -

No, el tipo definido por el usuario es ShapeType. Lea sobre typedef: en.wikipedia.org/wiki/Typedef -

Una typedef en Objective-C es exactamente lo mismo que una typedef en C. Y una enumeración en Objective-C es exactamente lo mismo que una enumeración en C. Esto declara una enumeración con tres constantes kCircle = 0, kRectangle = 1 y kOblateSpheroid = 2, y le da al tipo de enumeración el nombre ShapeType. Si no sabe qué significa "typedef" y "enum", compre un libro sobre C. -

13 Respuestas

Aquí se declaran tres cosas: se declara un tipo enumerado anónimo, ShapeType se declara un typedef para esa enumeración anónima, y ​​los tres nombres kCircle, kRectangle y kOblateSpheroid se declaran como constantes integrales.

Analicemos eso. En el caso más simple, una enumeración se puede declarar como

enum tagname { ... };

Esto declara una enumeración con la etiqueta tagname. En C y Objective-C (pero no C ++), cualquier referencia a este debe: ir precedido del enum palabra clave. Por ejemplo:

enum tagname x;  // declare x of type 'enum tagname'
tagname x;  // ERROR in C/Objective-C, OK in C++

Para evitar tener que utilizar el enum palabra clave en todas partes, se puede crear un typedef:

enum tagname { ... };
typedef enum tagname tagname;  // declare 'tagname' as a typedef for 'enum tagname'

Esto se puede simplificar en una línea:

typedef enum tagname { ... } tagname;  // declare both 'enum tagname' and 'tagname'

Y finalmente, si no necesitamos poder usar enum tagname con el enum palabra clave, podemos hacer enum anónimo y solo declararlo con el nombre typedef:

typedef enum { ... } tagname;

Ahora, en este caso, estamos declarando ShapeType para ser un nombre definido por el tipo de una enumeración anónima. ShapeType es realmente un tipo integral, y solo debe usarse para declarar variables que contienen uno de los valores enumerados en la declaración (es decir, uno kCircle, kRectangle y kOblateSpheroid). Puede asignar un ShapeType Sin embargo, variable otro valor mediante la conversión, por lo que debe tener cuidado al leer los valores de enumeración.

Finalmente, kCircle, kRectangle y kOblateSpheroid se declaran como constantes integrales en el espacio de nombres global. Dado que no se especificaron valores específicos, se asignan a enteros consecutivos que comienzan con 0, por lo que kCircle es 0, kRectangle es 1, y kOblateSpheroid es 2.

Respondido 22 Abr '12, 01:04

Buena explicación: solo para agregar una cosa, las estructuras siguen reglas de nomenclatura similares en C (no estoy seguro de Objective-C). - miguel rebabas

Objective-C es un superconjunto adecuado de C. Todas las reglas de denominación de estructuras de C en C son igualmente válidas en Objective-C. - jugo de sig

Impresionante. ¿Puedo usar enumeración de estilo C ++ y tampoco necesito escribir enumeración :) - user4951

Puede utilizar enumeraciones de estilo C ++ si el archivo en el que las declara es un archivo .mm en lugar de .m. Objective-C ++ es absurdamente poderoso. - kevin hoffmann

Y una vez que hayas comprendido esta respuesta, vale la pena mirar los nuevos NS_ENUM y NS_OPTIONS. Tutorial aquí: nshipster.com/ns_enum-ns_options y ASÍ que aquí: stackoverflow.com/questions/14080750/… - accidente de nieve

Apple recomienda definir enumeraciones como esta ya que Xcode 4.4:

typedef enum ShapeType : NSUInteger {
    kCircle,
    kRectangle,
    kOblateSpheroid
} ShapeType;

También proporcionan una práctica macro NS_ENUM:

typedef NS_ENUM(NSUInteger, ShapeType) {
    kCircle,
    kRectangle,
    kOblateSpheroid
};

Estas definiciones proporcionan una verificación de tipos más sólida y una mejor finalización del código. No pude encontrar documentación oficial de NS_ENUM, pero puede ver el video "Modern Objective-C" de la sesión de WWDC 2012 aquí.


ACTUALIZACIÓN
Enlace a documentación oficial aquí.

Respondido el 20 de junio de 20 a las 10:06

La parte sobre "Mejoras de enumeración" comienza a las 5:58 - vikingosegundo

Como se comentó en otra respuesta, consulte la explicación de Apple NS_ENUM macro de NSHipster: NSHipster.com/ns_enum-ns_options - Albahaca bourque

Este es el enlace a la documentación oficial sobre NS_ENUM: desarrollador.apple.com/library/ios/releasenotes/ObjectiveC/… - YoGiN

Una enumeración declara un conjunto de valores ordenados; el typedef solo agrega un nombre útil a esto. El primer elemento es 1, etc.

typedef enum {
Monday=1,
...
} WORKDAYS;

WORKDAYS today = Monday;

Lo anterior es solo una enumeración de las etiquetas shapeType.

Respondido el 20 de diciembre de 18 a las 02:12

Un tipo definido por el usuario que tiene los valores posibles de kCircle, kRectangleo kOblateSpheroid. Sin embargo, los valores dentro de la enumeración (kCircle, etc.) son visibles fuera de la enumeración. Es importante tener eso en cuenta (int i = kCircle; es válido, por ejemplo).

Respondido 01 Oct 12, 11:10

Actualización para cambio de 64 bits: Según documentos de Apple sobre cambios de 64 bits,

Las enumeraciones también se escriben: en el compilador LLVM, los tipos enumerados pueden definir el tamaño de la enumeración. Esto significa que algunos tipos enumerados también pueden tener un tamaño mayor de lo esperado. La solución, como en todos los demás casos, es no hacer suposiciones sobre el tamaño de un tipo de datos. En su lugar, asigne los valores enumerados a una variable con el tipo de datos adecuado

Entonces tienes que crear enumeración con tipo como la siguiente sintaxis si es compatible con 64 bits.

typedef NS_ENUM(NSUInteger, ShapeType) {
    kCircle,
    kRectangle,
    kOblateSpheroid
};

or

typedef enum ShapeType : NSUInteger {
   kCircle,
   kRectangle,
   kOblateSpheroid
} ShapeType;

De lo contrario, dará lugar a una advertencia como Implicit conversion loses integer precision: NSUInteger (aka 'unsigned long') to ShapeType

Actualización para programación rápida:

En rápido, hay un cambio de sintaxis.

enum ControlButtonID: NSUInteger {
        case kCircle , kRectangle, kOblateSpheroid
    }

Respondido 04 Jul 19, 15:07

Si necesita reenviar declare enum (NS_ENUM): stackoverflow.com/a/42009056/342794 - lal

La enumeración (abreviatura de enumeración) se utiliza para enumerar un conjunto de valores (enumeradores). Un valor es una cosa abstracta representada por un símbolo (una palabra). Por ejemplo, una enumeración básica podría ser

enum { xs,s,m,l,xl,xxl,xxxl,xxxxl };

Esta enumeración se llama anónima porque no tiene un símbolo para nombrarla. Pero sigue siendo perfectamente correcto. Solo úsalo así

enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize;

Está bien. La vida es hermosa y todo va bien. Pero un día necesita reutilizar esta enumeración para definir una nueva variable para almacenar myGrandFatherPantSize, luego escribe:

enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize;
enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandFatherPantSize;

Pero luego tiene un error del compilador "redefinición del enumerador". En realidad, el problema es que el compilador no está seguro de que primero enum y en segundo lugar describa lo mismo.

Luego, si desea reutilizar el mismo conjunto de enumeradores (aquí xs ... xxxxl) en varios lugares, debe etiquetarlo con un nombre único. La segunda vez que uses este set solo tienes que usar la etiqueta. Pero no olvide que esta etiqueta no reemplaza la palabra de enumeración, sino solo el conjunto de enumeradores. Luego tenga cuidado de usar enum como de costumbre. Como esto:

// Here the first use of my enum
enum sizes { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize; 
// here the second use of my enum. It works now!
enum sizes myGrandFatherPantSize;

también puede usarlo en una definición de parámetro:

// Observe that here, I still use the enum
- (void) buyANewDressToMyGrandMother:(enum sizes)theSize;

Se podría decir que reescribir la enumeración en todas partes no es conveniente y hace que el código se vea un poco extraño. Tienes razón. Un tipo real sería mejor.

Este es el paso final de nuestra gran progresión hacia la cumbre. Con solo agregar un typedef, transformemos nuestra enumeración en un tipo real. Oh, lo último, typedef no está permitido dentro de tu clase. Luego defina su tipo justo arriba. Hazlo asi:

// enum definition
enum sizes { xs,s,m,l,xl,xxl,xxxl,xxxxl };
typedef enum sizes size_type

@interface myClass {
   ...
   size_type myGrandMotherDressSize, myGrandFatherPantSize;
   ...
}

Recuerde que la etiqueta es opcional. Entonces, dado que aquí, en ese caso, no etiquetamos a los enumeradores sino solo para definir un nuevo tipo. Entonces realmente ya no lo necesitamos.

// enum definition
typedef enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } size_type;

@interface myClass : NSObject {
  ...
  size_type myGrandMotherDressSize, myGrandFatherPantSize;
  ...
}
@end

Si está desarrollando en Objective-C con XCode, le dejo descubrir algunas macros agradables con el prefijo NS_ENUM. Eso debería ayudarlo a definir buenas enumeraciones fácilmente y, además, ayudará al analizador estático a realizar algunas comprobaciones interesantes antes de compilar.

¡Buen Enum!

Respondido 13 Feb 19, 14:02

Siempre pensé "¿por qué alguien respondería una pregunta que ya está respondida y aceptada?". ¡Chico, estaba equivocado todo el tiempo! ¡Esta es la mejor respuesta y ayuda a principiantes como yo! - desarrollo de aplicaciones rak

typedef es útil para redefinir el nombre de un tipo de variable existente. Proporciona una forma breve y significativa de llamar a un tipo de datos. p.ej:

typedef unsigned long int TWOWORDS;

aquí, el tipo unsigned long int se redefine para ser del tipo TWOWORDS. Por lo tanto, ahora podemos declarar variables de tipo unsigned long int escribiendo,

TWOWORDS var1, var2;

en lugar de

unsigned long int var1, var2;

Respondido el 18 de junio de 13 a las 07:06

typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;

entonces puedes usarlo como: -

 ShapeType shape;

y

 enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} 
ShapeType;

ahora puedes usarlo como: -

enum ShapeType shape;

respondido 19 mar '16, 07:03

enum se usa para asignar valor a los elementos enum que no se pueden hacer en la estructura. Entonces, cada vez que en lugar de acceder a la variable completa, podemos hacerlo por el valor que asignamos a las variables en enum. Por defecto comienza con la asignación 0 pero podemos asignarle cualquier valor y a la siguiente variable en enum se le asignará un valor el valor anterior +1.

respondido 16 mar '14, 12:03

Puede usar en el siguiente formato, valor predeterminado sin formato a partir de 0, por lo que

  • kCircle es 0,
  • kRectangle es 1,
  • kOblateSpheroid es 2.

Puede asignar su propio valor de inicio específico.

typedef enum : NSUInteger {
    kCircle, // for your value; kCircle = 5, ...
    kRectangle,
    kOblateSpheroid
} ShapeType;

ShapeType circleShape = kCircle;
NSLog(@"%lu", (unsigned long) circleShape); // prints: 0

respondido 30 mar '16, 10:03

Un typedef permite al programador definir un tipo de Objective-C como otro. Por ejemplo,

typedef int Contador; define el tipo Counter para que sea equivalente al tipo int. Esto mejora drásticamente la legibilidad del código.

Respondido el 27 de diciembre de 14 a las 22:12

Typedef es una palabra clave en C y C ++. Se utiliza para crear nuevos nombres para tipos de datos básicos. (char, int, float, double, struct y enum).

typedef enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} ShapeType;

Aquí crea el tipo de datos enumerados Tipo de forma & podemos escribir nuevos nombres para el tipo de enumeración Tipo de forma como se indica a continuación

ShapeType shape1; 
ShapeType shape2; 
ShapeType shape3;

respondido 16 nov., 15:12

enum puede reducir muchos tipos de "errores" y hacer que el código sea más manejable

#define STATE_GOOD 0
#define STATE_BAD 1
#define STATE_OTHER 2
int STATE = STATE_OTHER

La definición no tiene restricciones. Es simplemente una sustitución. No puede limitar todas las condiciones del estado. Cuando el ESTADO se asigna a 5, el programa será incorrecto, porque no hay un estado coincidente. Pero el compilador no va a advertir STATE = 5

Entonces es mejor usar así

typedef enum SampleState {
    SampleStateGood  = 0,
    SampleStateBad,
    SampleStateOther
} SampleState;

SampleState state = SampleStateGood;

Respondido el 21 de junio de 18 a las 07:06

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.