¿Cuándo debería usar NSInteger
vs. int cuando desarrolle para iOS? Veo en el código de muestra de Apple que usan NSInteger
(o NSUInteger
) cuando pasan un valor como argumento a una función o devuelven un valor de una función.
- (NSInteger)someFunc;...
- (void)someFuncWithInt:(NSInteger)value;...
Pero dentro de una función solo están usando int
para rastrear un valor
for (int i; i < something; i++)
...
int something;
something += somethingElseThatsAnInt;
...
He leído (me han dicho) que NSInteger
es una forma segura de hacer referencia a un número entero en un entorno de 64 bits o de 32 bits, ¿por qué usarlo int
?
fuente
int
sea más adecuado incluso para unlong
. Tal vez sepa que no excederá un cierto rango y, por lo tanto, cree que será más eficiente en cuanto a memoria para usar simplementeint
.NSInteger
para pasar valores ay desde una API que lo especifica. Aparte de eso, no tiene ninguna ventaja sobre un int o un largo. Al menos con un int o un largo, usted sabe qué especificadores de formato usar en una declaración printf o similar.Por que usar
int
en absoluto?Apple usa
int
porque para una variable de control de bucle (que solo se usa para controlar las iteraciones del bucle) elint
tipo de datos está bien, tanto en el tamaño del tipo de datos como en los valores que puede contener para su bucle. No es necesario un tipo de datos dependiente de la plataforma aquí.Para una variable de control de bucle, incluso un bit de 16 bits funcionará laint
mayor parte del tiempo.Apple usa
NSInteger
para un valor de retorno de función o para un argumento de función porque en este caso el tipo de datos [tamaño] importa , porque lo que está haciendo con una función es comunicar / pasar datos con otros programas o con otros códigos; vea la respuesta a ¿ Cuándo debería usar NSInteger vs int? en tu pregunta misma ...fuente
OS X es "LP64". Esto significa que:
int
siempre es de 32 bits.long long
siempre es de 64 bits.NSInteger
ylong
siempre son del tamaño de un puntero. Eso significa que son de 32 bits en sistemas de 32 bits y de 64 bits en sistemas de 64 bits.La razón por la que NSInteger existe es porque muchas API heredadas se usaron incorrectamente en
int
lugar delong
contener variables de tamaño de puntero, lo que significaba que las API tenían que cambiar deint
along
en sus versiones de 64 bits. En otras palabras, una API tendría firmas de función diferentes dependiendo de si está compilando para arquitecturas de 32 bits o 64 bits.NSInteger
pretende enmascarar este problema con estas API heredadas.En su nuevo código, úselo
int
si necesita una variable de 32 bits,long long
si necesita un número entero de 64 bits y /long
oNSInteger
si necesita una variable de tamaño de puntero.fuente
int32_t
. Si necesita un uso entero de 64 bitsint64_t
. Si necesita una variable de tamaño puntero, useintptr_t
.<stdint.h>
tipos existen para ese propósito.LP64
no garantiza quelong long
sea de 64 bits. UnaLP64
plataforma podría elegir tenerlong long
un número entero de 128 bits.Si profundiza en la implementación de NSInteger:
Simplemente, el tipo de definición NSInteger hace un paso por usted: si la arquitectura es de 32 bits, usa
int
, si es de 64 bits, usalong
. Con NSInteger, no necesita preocuparse por la arquitectura en la que se ejecuta el programa.fuente
long long
. Por lo tanto, todos los tipos numéricos usarán el mismo especificador de tipo.NSLog("%@", @(1123));
NSLog("%li", (long)theNSInteger);
Debe usar NSIntegers si necesita compararlos con valores constantes como NSNotFound o NSIntegerMax, ya que estos valores diferirán en los sistemas de 32 bits y 64 bits, por lo tanto, valores de índice, recuentos y similares: use NSInteger o NSUInteger.
No hace daño usar NSInteger en la mayoría de las circunstancias, excepto que ocupa el doble de memoria. El impacto en la memoria es muy pequeño, pero si tiene una gran cantidad de números flotando en cualquier momento, puede ser diferente usar ints.
Si usa NSInteger o NSUInteger, querrá convertirlos en enteros largos o enteros largos sin signo cuando use cadenas de formato, ya que la nueva función Xcode devuelve una advertencia si intenta cerrar sesión en un NSInteger como si tuviera una longitud conocida. De manera similar, debe tener cuidado al enviarlos a variables o argumentos que se escriben como ints, ya que puede perder algo de precisión en el proceso.
En general, si no espera tener cientos de miles de ellos en la memoria a la vez, es más fácil usar NSInteger que preocuparse constantemente por la diferencia entre los dos.
fuente
A partir de este momento (septiembre de 2014), recomendaría usarlo
NSInteger/CGFloat
al interactuar con las API de iOS, etc., si también está creando su aplicación para arm64. Esto se debe a que es probable que obtenga resultados inesperados cuando use elfloat
,long
yint
tipos.EJEMPLO: FLOTADOR / DOBLE vs CGFLOAT
Como ejemplo tomamos el método delegado UITableView
tableView:heightForRowAtIndexPath:
.En una aplicación de solo 32 bits, funcionará bien si se escribe así:
float
es un valor de 32 bits y el 44 que está devolviendo es un valor de 32 bits. Sin embargo, si compilamos / ejecutamos este mismo código en una arquitectura arm64 de 64 bits, el 44 será un valor de 64 bits. Devolver un valor de 64 bits cuando se espera un valor de 32 bits dará una altura de fila inesperada.Puede resolver este problema utilizando el
CGFloat
tipoEste tipo representa un
float
entorno de 32 bits en un entorno de 32 bits y uno de 64 bits.double
en un entorno de 64 bits. Por lo tanto, al usar este tipo, el método siempre recibirá el tipo esperado independientemente del entorno de compilación / tiempo de ejecución.Lo mismo es cierto para los métodos que esperan enteros. Dichos métodos esperarán un
int
valor de 32 bits en un entorno de 32 bits y un valor de 64 bitslong
en un entorno de 64 bits. Puede resolver este caso utilizando el tipoNSInteger
que sirve comoint
olong
basado en el entorno de compilación / tiempo de ejecución.fuente
En iOS, actualmente no importa si usa
int
oNSInteger
. Importará más si / cuando iOS se mueve a 64 bits.En pocas palabras,
NSInteger
s sonint
s en código de 32 bits (y, por lo tanto, de 32 bits de longitud) ylong
s en código de 64 bits (long
s en código de 64 bits tienen 64 bits de ancho, pero 32 bits en código de 32 bits). La razón más probable para usar enNSInteger
lugar delong
es no romper el código de 32 bits existente (que usaint
s).CGFloat
tiene el mismo problema: en 32 bits (al menos en OS X), esfloat
; en 64 bits, esdouble
.Actualización: con la introducción del iPhone 5s, iPad Air, iPad Mini con Retina e iOS 7, ahora puede crear código de 64 bits en iOS.
Actualización 2: Además, el uso de
NSInteger
s ayuda con la interoperabilidad del código Swift.fuente
int = 4 byte (tamaño fijo independiente del arquitecto) NSInteger = depende del tamaño del arquitecto (p. ej., para 4 byte architect = 4 byte NSInteger size)
fuente