¿Cómo convertir un NSInteger en un int?

97

Por ejemplo, al pasar un valuemensaje a una NSIntegerinstancia como esta

[a value] provoca un EXC_BAD_ACCESS.

Entonces, ¿cómo convertir un NSIntegera int?

Si es relevante, solo se utilizan números pequeños <32.

Jeffrey
fuente
2
Pareces estar bastante confundido. [un valor] sugiere que espera que a sea un objeto, pero que es un NSInteger en este momento. "Convertir" a un int no resolverá ese problema.
Mike Abdullah

Respuestas:

205

Ta da:

NSInteger myInteger = 42;
int myInt = (int) myInteger;

NSIntegerno es más que un int de 32/64 bits. (usará el tamaño apropiado según el sistema operativo / plataforma que esté ejecutando)

Dave DeLong
fuente
13
Para ser precisos, creo que NSInteger es un int en plataformas de 32 bits y un long en plataformas de 64 bits.
Frédéric Adda
5
Recibo una advertencia usando el "casting" sugerido: la conversión implícita pierde precisión entera: 'NSUInteger' (también conocido como 'unsigned long') a 'int'
djcj
@djcj, sí, la respuesta no es correcta para los nuevos SDK. Yo creo que.
Azik Abdullah
¿No sería mucho más fácil poner (int) delante del NSInteger? Por ejemplo, (int) myInteger siempre que desee llamar al formulario entero, para que no tenga que crear una nueva variable.
chandhooguy
2
@chandhooguy, ¿por qué intentas evitar una nueva variable?
Dan Rosenstark
28

Si desea hacer esto en línea, simplemente transmita NSUIntegero NSIntegera un int:

int i = -1;
NSUInteger row = 100;
i > row // true, since the signed int is implicitly converted to an unsigned int
i > (int)row // false
Samuel Clay
fuente
1
Solo por curiosidad, ¿por qué publicas una respuesta 2 años después del hecho en una pregunta que ya tiene una respuesta aceptada con votos de dos dígitos? Especialmente porque el tuyo es solo una reformulación de esa respuesta.
Lily Ballard
6
Porque mi respuesta es una sola línea (usando un tipo de conversión en línea, el (int)), que creo que es lo que podría querer el OP. Yo mismo miré esto y noté que todas las respuestas sobre el tema eran de varias líneas.
Samuel Clay
2
La respuesta aceptada demuestra una conversión implícita utilizando una sola línea. La respuesta de Abizern explica que se producirá una conversión implícita si intenta utilizar un NSIntegervalor en lugar de un int. En ningún caso es una solución multilínea.
Lily Ballard
25
Debería haber sido más claro. Dado que esta es una pregunta un tanto novato, puede que no sea obvio para el programador novato que pueden convertir en línea con una expresión (int). Las otras respuestas no muestran esto y creo que ayuda a cualquiera que se tropiece en esta página.
Samuel Clay
4
Y tropecé con esta página un año y medio más tarde, necesitando específicamente el elenco relacionado con NSUInteger . ¡Gracias, Samuel!
leanne
18

No estoy seguro de las circunstancias en las que necesita convertir un NSIntegeren un int.

NSInteger es solo un typedef:

NSInteger Se utiliza para describir un número entero independientemente de si está compilando para un sistema de 32 bits o de 64 bits.

#if __LP64__ || TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64 
typedef long NSInteger;
#else
typedef int NSInteger;
#endif

Puede usar NSIntegercualquier lugar que use intsin convertirlo.

Abizern
fuente
2
Aquí hay una buena razón para querer convertir un NSUinteger en un int: comparaciones de valor. (int i = -1)> (NSUinteger j = 14) convierte el int a unsigned, lo que significa -1> 14, que no es lo que desea.
Samuel Clay
1
@SamuelClay. Un buen punto cuando se usa en casos específicos. Personalmente, convertiría un NSUInteger en un uint. Sin embargo. La pregunta era sobre convertir NSInteger, no NSUInteger.
Abizern
Solo utilicé un int sin firmar para ilustrar un error común. Es el mismo tipo de elenco para ambos, como demuestra mi respuesta. No es un problema difícil, pero es bastante común y todavía no he visto a nadie recomendar una respuesta de una sola línea.
Samuel Clay
0

Usado comúnmente en UIsegmentedControl, aparece un "error" al compilar en 64 bits en lugar de 32 bits, una forma fácil de no pasarlo a una nueva variable es usar estos consejos, agregar (int) :

[_monChiffre setUnite:(int)[_valUnites selectedSegmentIndex]];

en vez de :

[_monChiffre setUnite:[_valUnites selectedSegmentIndex]];
grominet
fuente