2010-02-11 9 views
12

Me preguntaba cuál es la razón detrás de diferentes estilos de declaración enum sobre el cacao?¿Por qué el cacao no usa el mismo estilo de declaración enum en todas partes?

De esta manera:

enum { constants.. }; typedef NSUInteger sometype; 

es la razón para usar typedef para obtener Traspaso a NSUInteger a trabajar sin poner?

A veces el typedef es de NSInteger/NSUInteger, ¿por qué no utilizar NSInteger siempre? ¿Hay algún beneficio real al utilizar NSUInteger?

Las etiquetas Enum se siguen usando a veces, como here en _NSByteOrder.

Esta respuesta también fue muy útil: What is a typedef enum in Objective-C?.

+1

typedef y enum son muy diferentes ... Realmente no entiendo su pregunta? enumeraciones se utilizan para configurar colecciones de constantes enteras con nombre. typedef se utilizan para dar un nuevo nombre a un tipo de datos, a menudo para admitir arquitecturas diferentes ... – t00ny

Respuesta

1

Mientras que usted podría utilizar algo como

typedef enum { constants... } sometype; 

no hay ninguna garantía sobre la eventual Bitsize del tipo de datos. Bueno, eso no es estrictamente cierto, pero es bastante cierto. Es mejor que las API se definan en tamaños de datos concretos, que con algo que puede cambiar según la configuración del compilador que se utilice.

2

Es la razón para utilizar typedef para obtener Traspaso a NSUInteger trabajar sin poner?

typedef se utiliza para especificar el tipo de base para los valores de enumeración. Siempre puede convertir un valor de enumeración a otro tipo, siempre que trunque el valor, mediante conversión a un tipo más pequeño (NSUInteger a unsigned short).

NSInteger y NSUInteger se introdujeron para facilitar la migración de aplicaciones de 64 bits, proporcionando un tipo independiente de arquitectura/plataforma para enteros con y sin signo. De esta forma, no importa cuántos bits tenga la CPU, las aplicaciones no necesitan ser reescritas.

veces el typedef es uno de NSInteger/NSUInteger, por qué no usar NSInteger siempre? ¿Hay algún beneficio real usando NSUInteger?

La elección depende de los valores en la enumeración. Algunos enumeraciones tienen una gran cantidad de valores, por lo que necesitan todos los bits disponibles:

  • NSInteger ofrece 2^31 valores positivos y negativos (en 32 bits de arquitectura).
  • NSUInteger ofrece 2^32 valores positivos (en la arquitectura de 32 bits).
  • Si su enumeración solo debe contener valores positivos, utilice NSUInteger.
  • Si su enumeración debe contener valores tanto positivos como negativos, utilice NSInteger.
  • NSUInteger se usa generalmente para la enumeración de banderas, ya que proporciona 32 valores distintos (en la arquitectura de 32 bits) para combinar a voluntad.

No sé si hay una regla de elección en el equipo de desarrollo de Apple para eso. Eso espero ...

+0

¿Quiere decir * 2 a la potencia de * 31 y 32, ¿verdad? Además, ambos tipos ofrecen 2 ** 32 valores distintos; la diferencia es que con un tipo firmado (como 'NSInteger'), la mitad de ellos (2 ** 31) son negativos, y aproximadamente la mitad (2 ** 31 - 1) son positivos. Con un tipo sin signo, todos los 2 ** 32 no son negativos. Y esa es la verdadera diferencia: si todos los valores de enumeración, alguna vez, van a ser positivos, puede declarar el tipo como 'NSUInteger'. Por el contrario, si va a tener valores negativos, debe usar 'NSInteger'. –

+0

Tienes razón. Estaba significando valores de bandera. He actualizado mi respuesta en consecuencia. –

12

varias razones:

Razón 1: Flexibilidad:

enum lickahoctor { yes = 0, no = 1, maybe = 2 }; 

declara una enumeración. Puede usar los valores yes, no y maybe en cualquier parte y asignarlos a cualquier tipo integral. También puede utilizar esto como un tipo, escribiendo

enum lickahoctor myVar = yes; 

Esto hace que sea agradable porque si una función tiene un parámetro con el tipo de enumeración lickahoctor sabrá que puede asignar yes, no o maybe a ella. Además, el depurador lo sabrá, por lo que mostrará el nombre simbólico en lugar del valor numérico. El problema es que el compilador solo le permitirá asignar valores que haya definido en enum lickahoctor a myVar. Si, por ejemplo, desea definir algunas banderas en la clase base, y luego agregar algunas banderas más en la subclase, no puede hacerlo de esta manera.

Si utiliza una int en su lugar, no tiene ese problema. Entonces, quiere usar algún tipo de int, para poder asignar constantes arbitrarias.

Razón 2: La compatibilidad binaria:

El compilador elige un buen tamaño que se ajusta a todas las constantes que ha definido en una enumeración. No hay garantía de lo que obtendrás. Por lo tanto, si escribe una estructura que contiene dicha variable directamente en un archivo, no hay garantía de que seguirá siendo del mismo tamaño cuando la vuelva a leer con la próxima versión de su aplicación (según el estándar C, al menos, - no es tan sombrío en la práctica).

Si utiliza algún tipo de int en su lugar, la plataforma generalmente garantiza un tamaño particular para ese número. Especialmente si usa uno de los tipos garantizados para un tamaño particular, como int32_t/uint32_t.

Razón 3: La legibilidad y la auto-documentación

Cuando se declara miVar anterior, es evidente de inmediato los valores que se puede poner en ella. Si solo usa un int, o un uint32_t, no lo es. Así que lo que hace es utilizar

enum { yes, no, maybe }; 
typedef uint32_t lickahoctor; 

para definir un buen nombre para el número entero algún lugar cerca de las constantes que recordar a la gente que una variable de este tipo puede contener este valor. Pero aún así obtiene el beneficio de un tamaño fijo y predecible y la capacidad de definir valores adicionales en subclases, si es necesario.

Razón 4: Apoyo a campos de bits

las variables de enumeración escrita a máquina única cesión de manutención exactamente un valor de sus opciones. Entonces, si intenta implementar un campo de bit, no puede escribirlo como un campo de bits. Además, debe usar variables sin signo para evitar que la extensión de signo lo atornille.

+0

No se garantiza que NSInteger tenga un tamaño particular, se garantiza que será diferente en 'i386' y' x86_64'. Si escribiste un archivo binario con un 'lickahoctor' en un Core Duo, actualizaste tu Mac y lo leíste de nuevo, la hilaridad se produciría. –

+0

Por supuesto, Graham. Brainfart allí. Gracias por corregir eso. – uliwitness

+2

+1 para 'lickahoctor', a pesar de que es una broma interna. – Abizern

Cuestiones relacionadas