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


No creo que entiendo fundamentalmente qué enum es, y cuándo usarlo.

Por ejemplo:

typedef enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} ShapeType;

¿Qué se está declarando realmente aquí?


1042
2018-04-01 21:59


origen


Respuestas:


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

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

enum tagname { ... };

Esto declara una enumeración con la etiqueta tagname. En C y Objective-C (pero no C ++), cualquier referencia a esto debe ser precedido con el 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 usar 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 sola 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 que enum anónimo y solo declararlo con el nombre typedef:

typedef enum { ... } tagname;

Ahora, en este caso, estamos declarando ShapeType ser un nombre de tipo definido 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, kRectangley kOblateSpheroid) Puedes asignar un ShapeType Sin embargo, varía otro valor por conversión, por lo que debes tener cuidado cuando leas valores enum.

Finalmente, kCircle, kRectangley 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 comenzando con 0, por lo que kCircle es 0, kRectangle es 1, y kOblateSpheroid es 2.


1532
2018-04-01 22:22



Apple recomienda definir enums como este desde 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 comprobación de tipos más sólida y una mejor finalizació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 de WWDC 2012 aquí.

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


240
2018-03-06 09:43



Una enumeración declara un conjunto de valores ordenados - typedef solo agrega un nombre práctico a esto. El primer elemento es 0, etc.

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

WORKDAYS today = Monday;

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


47
2018-03-15 16:31



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).


34
2018-04-01 22:04



Actualización para cambio de 64 bits: De acuerdo a Apple Docs cambios de alrededor de 64 bits,

Las enumeraciones también se escriben: en el compilador LLVM, los tipos enumerados pueden   define el tamaño de la enumeración. Esto significa que algunos enumerados   los tipos también pueden tener un tamaño que es más grande de lo que esperaba. los   solución, como en todos los demás casos, es no hacer suposiciones sobre una   tamaño del tipo de datos En cambio, asigne cualquier valor enumerado a una variable   con el tipo de datos adecuado

Entonces tienes que crear enum con tipo como la sintaxis siguiente 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 como Implicit conversion loses integer precision: NSUInteger (aka 'unsigned long') to ShapeType

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

Rápidamente, hay un cambio de sintaxis.

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

28
2018-01-29 13:08



Enum es un tipo de datos definido por el usuario. TIPOS DE DATOS ENUMERADOS Las variables de tipo de datos enumerados solo pueden asumir valores que han sido declarados 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 enumerado. Consiste en un conjunto de valores, enero a diciembre. Numéricamente, a jan se le asigna el valor 1, al valor 2, y así sucesivamente.

La variable this_month se declara del mismo tipo que month, luego se le asigna el valor asociado con feb. A this_month no se le pueden asignar valores fuera de los especificados en la lista de inicialización para la declaración del mes.


25
2017-10-17 12:08



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 hermosa y todo va bien. Pero un día necesitas reutilizar esta enumeración para definir una nueva variable para almacenar myGrandFatherPantSize, luego escribes:

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 de compilación "redefinición del enumerador". En realidad, el problema es que el compilador no está seguro de que primero enum y el segundo 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 usa este conjunto, solo tiene 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 enum 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;

también puedes 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 enum 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 último paso de nuestra gran progresión a la cumbre. Simplemente agregando un typedef vamos a transformar nuestra enum en un tipo real. Por último, typedef no está permitido dentro de su 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 debemos etiquetar a los enumeradores sino simplemente definir 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 permite descubrir algunas bonitas macros con el prefijo NS_ENUM. Eso debería ayudarte a definir buenas enumeraciones fácilmente y, además, ayudará al analizador estático a hacer algunas comprobaciones interesantes antes de compilar.

Buen Enum!


23
2018-03-10 18:23