objective-c enums typedef

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



enums (14)

Apple recomienda definir enums como este desde Xcode 4.4:

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

También proporcionan una macro útil NS_ENUM:

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

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

ACTUALIZACIÓN: Enlace a la documentación oficial here .

No creo que entienda fundamentalmente qué es una enum y cuándo usarla.

Por ejemplo:

typedef enum { kCircle, kRectangle, kOblateSpheroid } ShapeType;

¿Qué está siendo realmente declarado aquí?


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

Vamos a romper eso. En el caso más simple, una enumeración puede ser declarada como

enum tagname { ... };

Esto declara una enumeración con la etiqueta tagname . En C y en Objective-C (pero no en C ++), cualquier referencia a esto debe ir precedida de la palabra clave enum . 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 usar la palabra clave enum 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 sola línea:

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

Y, finalmente, si no necesitamos poder usar enum tagname con la palabra clave enum , podemos hacer que la enum anónima y solo declararla con el nombre typedef:

typedef enum { ... } tagname;

Ahora, en este caso, estamos declarando que ShapeType es un nombre escrito de una enumeración anónima. ShapeType es realmente solo un tipo integral, y solo debe usarse para declarar variables que contienen uno de los valores listados en la declaración (es decir, uno de kCircle , kRectangle , y kOblateSpheroid ). Sin embargo, puede asignar otro valor a la variable ShapeType mediante el lanzamiento, 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. Como 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.


El 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í se crea el tipo de datos enumerado ShapeType y podemos escribir nuevos nombres para el tipo de enumeración ShapeType como se indica a continuación

ShapeType shape1; ShapeType shape2; ShapeType shape3;


Enum es el tipo de datos definido por el usuario. TIPOS DE DATOS ENUMERADOS Las variables de tipos de datos enumerados solo pueden asumir valores que se han declarado previamente.

enum month { jan = 1, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec }; enum month this_month; this_month = feb;

En la declaración anterior, el mes se declara como un tipo de datos enumerados. Consiste en un conjunto de valores, jan a dec. Numéricamente, a jan se le da el valor 1, feb el valor 2, y así sucesivamente.

La variable this_month se declara del mismo tipo que mes, luego se le asigna el valor asociado a feb. A este mes no se le puede asignar ningún valor fuera de los especificados en la lista de inicialización para la declaración del mes.


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 es capaz de 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 avisará al ESTADO = 5

Así que es mejor usar así

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


La enumeración (abreviatura de enumeración) se usa para enumerar un conjunto de valores (enumeradores). Un valor es cualquier 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;

De acuerdo. La vida es bella 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 entonces tienes un error de compilación "redefinición de enumerador". En realidad, el problema es que el compilador no está seguro de enumerar primero y de que el segundo describe 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 enum, sino solo el conjunto de enumeradores. Luego, tenga cuidado de usar la enumeración como de costumbre. Me gusta 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;

Puedes usarlo también 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 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. Simplemente agregando un typedef vamos a transformar nuestra enumeración en un tipo real. Oh, una última cosa, typedef no está permitido dentro de tu clase. Luego define tu 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; ... }

Recuerda que la etiqueta es opcional. Entonces, ya que aquí, en ese caso, no etiquetamos a los enumeradores sino que definimos un nuevo tipo. Entonces ya no lo necesitamos más.

// 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 ObjectiveC con XCode, le permito descubrir algunas macros agradables con el prefijo NS_ENUM. Eso debería ayudarlo a definir buenos enums fácilmente y, además, ayudará al analizador estático a realizar algunas verificaciones interesantes antes de compilar.

Buen enum!


Se puede usar en el formato a continuación, el valor predeterminado bruto desde 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


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


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

typedef int Counter; Define que el tipo de contador es equivalente al tipo int. Esto mejora drásticamente la legibilidad del código.


Una enumeración declara un conjunto de valores ordenados; typedef simplemente agrega un nombre práctico a esto. El 1er elemento es 0 etc.

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

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


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


typedef es útil para redefinir el nombre de un tipo de variable existente. Proporciona una forma corta 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;


Actualización para el cambio de 64 bits: Según los documentos de Apple sobre los 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 que el 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 cualquier valor enumerado a una variable con el tipo de datos adecuado

Por lo tanto, debe crear la enumeración con el tipo como se indica a continuación en la sintaxis si admite 64 bits.

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

o

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

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

Actualización para la programación rápida:

En veloz, hay un cambio de sintaxis.

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


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;