NSInteger myInt = 1804809223;
NSLog(@"%i", myInt); <====
El código anterior produce un error:
Los valores de tipo 'NSInteger' no deben usarse como argumentos de formato; agregue un reparto explícito a 'largo' en su lugar
El NSLog
mensaje corregido es en realidad NSLog(@"%lg", (long) myInt);
. ¿Por qué tengo que convertir el valor entero de myInt
a long
si quiero que se muestre el valor?
objective-c
xcode
casting
nsinteger
Daniel Lee
fuente
fuente
NSLog(@"%ld", (long) myInt);
, ellong
reparto es para que coincida con ell
calificador de%ld
, pero todo eso es innecesario, ya queNSLog(@"%d", myInt);
es suficiente (dado que podemos ver quemyInt
no eslong
. En pocas palabras, se echómyInt
si se utiliza mucho en el formato de clasificación cadena, pero no es necesario usar el calificador de formato de cadena larga olong
emitir aquí.NSInteger
es larga), pero parece que está compilando con el objetivo de OS X (donde está ).NSInteger
long
Respuestas:
Recibirá esta advertencia si compila en OS X (64 bits), porque en esa plataforma
NSInteger
se define comolong
y es un entero de 64 bits. El%i
formato, por otro lado, es paraint
, que es de 32 bits. Por lo tanto, el formato y el parámetro real no coinciden en tamaño.Dado que
NSInteger
es de 32 bits o de 64 bits, dependiendo de la plataforma, el compilador recomienda agregar un reparto enlong
general.Actualización: dado que iOS 7 ahora también es compatible con 64 bits, puede obtener la misma advertencia al compilar para iOS.
fuente
NSLog(@"%ld", (long) myInt)
, funciona correctamente en 32 bits y 64 bits.long myInt = [myNumber longValue];
. Pero muchos métodos Foundation (Core) usan NS (U) Integer como parámetro o valor de retorno, por lo que el problema general persiste. También puede tener sentido en su aplicación usar NS (U) Integer para obtener un mayor rango disponible en dispositivos de 64 bits.No tiene que emitir nada si sus especificadores de formato coinciden con sus tipos de datos. Consulte la respuesta de Martin R para obtener detalles sobre cómo
NSInteger
se define en términos de tipos nativos.Entonces, para el código destinado a ser construido para entornos de 64 bits, puede escribir sus declaraciones de registro de esta manera:
mientras que para entornos de 32 bits puede escribir:
y todo funcionará sin yeso.
Una razón para usar conversiones de todos modos es que un buen código tiende a ser portado a través de plataformas, y si convierte sus variables explícitamente, se compilará limpiamente en 32 y 64 bits:
Y tenga en cuenta que esto es cierto no solo para las declaraciones NSLog, que son solo ayudas para la depuración, sino también para
[NSString stringWithFormat:]
los diversos mensajes derivados, que son elementos legítimos del código de producción.fuente
En lugar de pasar un NSInteger a NSLog, simplemente pase un NSNumber. Esto evitará todos los modelos y elegirá el especificador de formato de cadena correcto.
También funciona para NSUIntegers sin tener que preocuparse por eso. Vea la respuesta a NSInteger y NSUInteger en un entorno mixto de 64 bits / 32 bits
fuente
Mantiene la advertencia durante el uso
NSLog(@"%ld", (long)myInt);
, pero detiene la advertencia después de la declaración de cambiolong myInt = 1804809223;
en iOS 10.fuente
OS X utiliza varios tipos de datos (NSInteger, NSUInteger, CGFloat y CFIndex) para proporcionar un medio consistente de representar valores en entornos de 32 y 64 bits. En un entorno de 32 bits, NSInteger y NSUInteger se definen como int y unsigned int, respectivamente. En entornos de 64 bits, NSInteger y NSUInteger se definen como largos y sin signo, respectivamente. Para evitar la necesidad de usar diferentes especificadores de tipo estilo printf según la plataforma, puede usar los especificadores que se muestran en este enlace para entornos de 32 bits y 64 bits.
fuente