ios - NSInteger y NSUInteger en un entorno mixto de 64 bits/32 bits
objective-c 64bit (3)
Creo que la forma más segura es encajonarlos en instancias de NSNumber
.
NSLog(@"Number is %@", @(number)); // use the highest level of abstraction
Este boxeo no suele tener que crear un nuevo objeto gracias a la magia del puntero etiquetado .
Si realmente no quiere usar NSNumber
, puede convertir tipos primitivos manualmente, como otros sugirieron:
NSLog(@"Number is %ld", (long)number); // works the same on 32-bit and 64-bit
Tengo una buena cantidad de especificadores de formato de cadena en NSLog / NSAssert, etc. llamadas que usan %d
y %u
con los tipos NSInteger (= int on 32bit)
y NSUInteger (= unsigned int on 32bit)
respectivamente.
Al convertir la aplicación a 64 bits, esto genera advertencias (por supuesto), ya que se espera %ld %lu
para lo que ahora se convirtió en un tipo long
y unsigned long
.
Por supuesto, la conversión de los especificadores de formato introducirá las advertencias inversas en la compilación de 32 bits.
Por lo tanto, la única solución que veo para liberarme de las advertencias es usar los especificadores de 64 bits y la conversión a los tipos de valor de 64 bits en todas partes donde se proporciona una advertencia en la versión de 32 bits.
¿Pero me preguntaba si tal vez existan especificadores de formato específicamente para el tipo NSInteger
y NSUInteger
que funcionen en ambas arquitecturas sin la conversión?
También puede usar %zd
( NSInteger
) y %tu
( NSUInteger
) al iniciar sesión en la consola.
NSInteger integer = 1;
NSLog(@"first number: %zd", integer);
NSUInteger uinteger = 1;
NSLog(@"second number: %tu", uinteger);
No , (desafortunadamente) no hay un formato printf que se corresponda directamente con el NS(U)Integer
. Por lo tanto, para el código de arquitectura independiente, debe convertir todo a la variante "larga" (como sugiere el "Fix-it" de Xcode):
NSInteger i = ...;
NSLog(@"%ld", (long)i);
La única alternativa que conozco es de los tipos de Foundation al compilar para la arquitectura arm64 y de 32 bits :
// In the precompiled header file:
#if __LP64__
#define NSI "ld"
#define NSU "lu"
#else
#define NSI "d"
#define NSU "u"
#endif
NSInteger i = ...;
NSLog(@"i=%"NSI, i);
el uso de macros preprocesador (pero incluso el autor de esa respuesta lo llama un "enfoque ciertamente horrible").