Cuál es la mejor manera de crear constantes en Objective-C
Estoy creando un cliente Reddit con fines de aprendizaje. Necesito un archivo con constantes. Estaba pensando en importar el archivo en el archivo Reddit-Prefix.pch
para hacer que las constantes estén disponibles para todos los archivos. ¿Es una buena manera de hacer las cosas? Además, he hecho mi investigación y he encontrado varios métodos para crear constantes, pero no se cual usar:
-
#define
macro const
static const
extern const
enum
Entonces, ¿cuál es el camino preferido? ¿Qué es la convención? Sé que "depende" pero mi pregunta más específica es: ¿Cuáles son los casos de uso para cada una de esas soluciones?
Además, si utilizo extern const
, ¿necesito importar el archivo, o las constantes estarán disponibles globalmente sin importar el archivo?
Una cosa que podría concluir lógicamente es que enum
es el la mejor opción al definir algo como dominios de error personalizados (¿tengo razón?). ¿Pero qué hay de los otros?
2 answers
La primera pregunta es qué alcance quieres que tengan tus constantes, que en realidad son dos preguntas:{[19]]}
- ¿Son estas constantes específicas de una sola clase, o tiene sentido tenerlas en toda la aplicación?
- Si son específicos de la clase, ¿son para uso de clientes de la clase, o solo dentro de la clase?
Si son específicos e internos de una sola clase, declararlos como static const
en la parte superior de la .archivo m, así:
static NSString *const MyThingNotificationKey = @"MyThingNotificationKey";
Si pertenecen a una sola clase, pero deben ser públicos / utilizados por otras clases, declararlos como extern
en el encabezado y definirlos en el .m:
//.h
extern NSString *const MyThingNotificationKey;
//.m
NSString *const MyThingNotificationKey = @"MyThingNotificationKey";
Si deben ser globales, declararlos en un encabezado y definirlos en un módulo correspondiente, específicamente para esas constantes.
Puede mezclar y combinar estas para diferentes constantes con diferentes niveles de cuán globales desea que sean, y para diferentes constantes globales que simplemente no pertenecen juntas,puede ponerlas en módulos separados, cada uno con su propio encabezado, si lo desea.
¿Por qué no #define
?
La antigua respuesta es "las macros no tienen información de tipo", pero los compiladores de hoy en día son bastante inteligentes al hacer toda la comprobación de tipos para literales (a qué macros se expanden), así como variables.
La respuesta moderna es porque el depurador no sabrá acerca de sus macros. No se puede decir [myThing addObserver:self forKey:MyThingNotificationKey]
en un comando de depurador si MyThingNotificationKey
es una macro; el depurador solo puede saberlo si es un variable.
¿Por qué no enum
?
Bueno, rmaddy me ganó en los comentarios: enum
solo puede definir constantes enteras. Cosas como números de identificación de serie, máscaras de bits, códigos de cuatro bytes, etc.
Para esos propósitos, enum
es genial y absolutamente debes usarlo. (Aún mejor, use las macros NS_ENUM
y NS_OPTIONS
.) Para otras cosas, debe usar otra cosa; enum
no hace nada más que números enteros.
Y otras cuestiones
Estaba pensando en importar el archivo con el prefijo Reddit.archivo pch para que las constantes estén disponibles para todos los archivos. Es una buena manera de hacer las cosas?
Probablemente inofensivo, pero probablemente excesivo. Importe sus encabezados de constantes donde los necesite.
¿Cuáles son los casos de uso para cada una de esas soluciones?
-
#define
: Bastante limitado. Honestamente no estoy seguro de que haya una buena razón para usar esto para constantes nunca más. -
const
: Mejor para constantes locales. Además, tienes que usar esto para uno que declaraste en un encabezado y ahora estás definiendo. -
static const
: Mejor para constantes específicas del archivo (o específicas de la clase). -
extern const
: Debe usar esto al exportar una constante en un encabezado.
Además, si utilizo
extern const
, ¿necesito importar el archivo, o las constantes estarán disponibles globalmente sin importar el archivo?
Necesita importar el archivo, ya sea en cada archivo donde lo use o en el encabezado de prefijo.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-22 09:09:22
FOUNDATION_EXPORT
Considere usar FOUNDATION_EXPORT
para un poco más de compatibilidad que extern
ya que está definido en foundation y compila a formatos compatibles para C, C++ y Win32.
Como se define en NSObjCRuntime.h
#if defined(__cplusplus)
#define FOUNDATION_EXTERN extern "C"
#else
#define FOUNDATION_EXTERN extern
#endif
#if TARGET_OS_WIN32
#if defined(NSBUILDINGFOUNDATION)
#define FOUNDATION_EXPORT FOUNDATION_EXTERN __declspec(dllexport)
#else
#define FOUNDATION_EXPORT FOUNDATION_EXTERN __declspec(dllimport)
#endif
#define FOUNDATION_IMPORT FOUNDATION_EXTERN __declspec(dllimport)
#else
#define FOUNDATION_EXPORT FOUNDATION_EXTERN
#define FOUNDATION_IMPORT FOUNDATION_EXTERN
#endif
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-14 19:46:38