Estoy desarrollando una aplicación Cocoa , y estoy usando NSString
s constantes como formas de almacenar nombres clave para mis preferencias.
Entiendo que esta es una buena idea porque permite cambiar fácilmente las claves si es necesario.
Además, es toda la noción de 'separar sus datos de su lógica'.
De todos modos, ¿hay una buena manera de definir estas constantes una vez para toda la aplicación?
Estoy seguro de que hay una manera fácil e inteligente, pero en este momento mis clases simplemente redefinen las que usan.
Respuestas:
Debe crear un archivo de encabezado como
(puede usar en
extern
lugar deFOUNDATION_EXPORT
si su código no se usará en entornos mixtos C / C ++ o en otras plataformas)Puede incluir este archivo en cada archivo que use las constantes o en el encabezado precompilado para el proyecto.
Define estas constantes en un archivo .m como
Constants.m debe agregarse al objetivo de su aplicación / marco para que esté vinculado al producto final.
La ventaja de usar constantes de cadena en lugar de constantes
#define
'd es que puede probar la igualdad usando la comparación de puntero (stringInstance == MyFirstConstant
), que es mucho más rápido que la comparación de cadena ([stringInstance isEqualToString:MyFirstConstant]
) (y más fácil de leer, IMO).fuente
NSString
propiedades encopy
lugar deretain
. Como tal, podrían (y deberían) mantener una instancia diferente de suNSString*
constante, y la comparación directa de direcciones de memoria fallaría. Además, presumiría que cualquier implementación razonablemente óptima de-isEqualToString:
comprobaría la igualdad del puntero antes de entrar en el meollo de la comparación de caracteres.La manera más fácil:
Mejor manera:
Una ventaja del segundo es que cambiar el valor de una constante no causa una reconstrucción de todo su programa.
fuente
extern NSString const * const MyConstant
, es decir, convertirlo en un puntero constante a un objeto constante en lugar de solo un puntero constante?También hay una cosa para mencionar. Si necesita una constante no global, debe usar la
static
palabra clave.Ejemplo
Debido a la
static
palabra clave, este const no es visible fuera del archivo.Corrección menor por @QuinnTaylor : las variables estáticas son visibles dentro de una unidad de compilación . Por lo general, este es un único archivo .m (como en este ejemplo), pero puede morderte si lo declaras en un encabezado que se incluye en otro lugar, ya que obtendrás errores de enlace después de la compilación
fuente
La respuesta aceptada (y correcta) dice que "puede incluir este archivo [Constants.h] ... en el encabezado precompilado para el proyecto".
Como novato, tuve dificultades para hacerlo sin más explicaciones: así es cómo: en su archivo YourAppNameHere-Prefix.pch (este es el nombre predeterminado para el encabezado precompilado en Xcode), importe sus Constantes.h dentro del
#ifdef __OBJC__
bloque .También tenga en cuenta que los archivos Constants.h y Constants.m no deben contener absolutamente nada más que lo que se describe en la respuesta aceptada. (Sin interfaz o implementación).
fuente
Generalmente estoy usando la forma publicada por Barry Wark y Rahul Gupta.
Aunque, no me gusta repetir las mismas palabras en los archivos .h y .m. Tenga en cuenta que en el siguiente ejemplo la línea es casi idéntica en ambos archivos:
Por lo tanto, lo que me gusta hacer es utilizar alguna maquinaria de preprocesador C. Déjame explicarte a través del ejemplo.
Tengo un archivo de encabezado que define la macro
STR_CONST(name, value)
:En mi par .h / .m donde quiero definir la constante, hago lo siguiente:
et voila, tengo toda la información sobre las constantes en el archivo .h solamente.
fuente
Yo mismo tengo un encabezado dedicado a declarar NSStrings constantes utilizados para preferencias de esta manera:
Luego declarándolos en el archivo .m adjunto:
Este enfoque me ha servido bien.
Editar: tenga en cuenta que esto funciona mejor si las cadenas se utilizan en varios archivos. Si solo lo usa un archivo, puede hacerlo
#define kNSStringConstant @"Constant NSString"
en el archivo .m que usa la cadena.fuente
Una ligera modificación de la sugerencia de @Krizz, para que funcione correctamente si el archivo de encabezado de constantes se va a incluir en la PCH, lo cual es bastante normal. Dado que el original se importa a la PCH, no lo volverá a cargar en el
.m
archivo y, por lo tanto, no obtendrá símbolos y el enlazador no está satisfecho.Sin embargo, la siguiente modificación le permite funcionar. Es un poco complicado, pero funciona.
Necesitará 3 archivos,
.h
archivo que tiene las definiciones constantes, el.h
archivo y el.m
archivo, usaréConstantList.h
,Constants.h
yConstants.m
, respectivamente. los contenidos deConstants.h
son simplemente:y el
Constants.m
archivo se ve así:Finalmente, el
ConstantList.h
archivo tiene las declaraciones reales y eso es todo:Un par de cosas a anotar:
Tuve que redefinir la macro en el
.m
archivo después de#undef
haberla usado para que se usara la macro.También tuve que usar en
#include
lugar de#import
esto para que funcione correctamente y evitar que el compilador vea los valores previamente compilados.Esto requerirá una recompilación de su PCH (y probablemente de todo el proyecto) cada vez que se modifiquen los valores, lo que no es el caso si están separados (y duplicados) como es normal.
Espero que sea útil para alguien.
fuente
extern
anterior con elFOUNDATION_EXPORT
.fuente
Como dijo Abizer, puede ponerlo en el archivo PCH. Otra forma que no es tan sucia es hacer un archivo de inclusión para todas sus claves y luego incluirlo en el archivo en el que está utilizando las claves o incluirlo en la PCH. Con ellos en su propio archivo de inclusión, que al menos le brinda un lugar para buscar y definir todas estas constantes.
fuente
Si quieres algo como constantes globales; una forma rápida y sucia es colocar las declaraciones constantes en el
pch
archivo.fuente
Intenta usar un método de clase:
Lo uso a veces.
fuente
isEqualToString:
para la comparación, que es un costo adicional en tiempo de ejecución. Cuando quieras constantes, haz constantes.Si le gusta la constante de espacio de nombres, puede aprovechar struct, Friday Q&A 2011-08-19: Constantes y funciones de espacios de nombres
fuente
__unsafe_unretained
calificador para que funcione.Utilizo una clase singleton, para poder burlarme de la clase y cambiar las constantes si es necesario para las pruebas. La clase de constantes se ve así:
Y se usa así (tenga en cuenta el uso de una abreviatura para las constantes c: ahorra escribir
[[Constants alloc] init]
cada vez):fuente
Si desea llamar a algo como esto
NSString.newLine;
desde el objetivo c, y desea que sea constante estática, puede crear algo como esto rápidamente:Y tiene una definición constante agradable y legible, y está disponible desde el tipo de su elección, mientras que el estilo está limitado al contexto de tipo.
fuente