objective c - NSNumber constantes en Obj-C
objective-c ios (4)
Quiero hacer algunas constantes NSNumber a través del mismo estilo utilizado para NSStrings en este tema . Es decir, estoy creando constantes.h / .m archivos separados e importándolos a las clases que necesitan acceder a ellos.
actualizar:
Años después, me di cuenta de que es posible crear una constante NSNumber para enteros ... pero es un hack:
#define CONST_INT_NSNUMBER( x ) ((__bridge NSNumber * const)(void * const)(( x << 8 ) | 0x27))
NSNumber * const number = CONST_INT_NSNUMBER(123) ;
Esto funciona porque ciertos NSNumbers enteros se almacenan como punteros etiquetados .
respuesta original:
No puedes hacerlo
NSNumber * const mynumber = @5.5;
da:
El elemento inicializador no es una constante de compilación
La implicación de que el compilador tiene una característica especial específicamente para crear objetos NSString
constantes en tiempo de NSString
, pero no cualquier otro tipo de objeto.
Usted podría hacer esto, sin embargo:
.h :
extern NSNumber * kConstantNumber ;
.m :
NSNumber * kConstantNumber ;
@implementation NSNumber (InitializeConstants)
+(void)load
{
kConstantNumber = @42;
// ... and the rest ...
}
@end
Básicamente puedes lograr cerca de lo que quieres en tres partes:
archivo .h:
extern NSNumber *MyFirstConstant;
archivo .m
NSNumber *MyFirstConstant;
AppDelegate.m
+(void)initialize
{
MyFirstConstant = @5;
...
}
Se garantiza que AppDelegate se ejecute antes que cualquiera de sus otros códigos, y la inicialización es el primer método que se llamará en AppDelegate, por lo que esencialmente puede asegurar que todas sus constantes estén configuradas antes de que se ejecute su aplicación.
Desafortunadamente, actualmente no puede generar constantes NSNumber
de la misma manera que puede generar constantes NSString
. Cuando intentes hacerlo obtendrás un error de compilación
NSNumber * const kNumberConstant = @2; // This doesn''t work.
Sin embargo, puedes usar primitivos en su lugar.
NSInteger const kSomeIntValue = 10;
El problema de hacer esto es que no existe un NSNumber constante de compilación. Sólo NSString obtiene esa distinción. NSNumbers siempre se crean dinámicamente. Puede falsificarlo utilizando una función que se ejecuta al inicio de su programa para inicializar las variables. Sus opciones:
Cree una clase con un método de
+load
que realice la inicialización.En el archivo con las constantes, incluya una función con
__attribute__((constructor))
. Así por ejemplo:// Constants.m NSNumber *someGlobalNumber; __attribute__((constructor)) static void InitGlobalNumber() { someGlobalNumber = [[NSNumber numberWithInteger:1] retain]; }
Pero, por supuesto, entonces no puede usar estos números de manera confiable en ninguna otra función que se ejecute tan temprano en el proceso de inicio. Esto generalmente no es un problema, pero vale la pena tenerlo en cuenta.
La otra opción, que he visto surgir varias veces, es tener una clase con accesores para los números en lugar de dar acceso directo a las variables. Es un diseño un poco más pesado, pero también se siente menos vudú, que tiene sus encantos.