2009-08-16 7 views

Respuesta

50

Las respuestas existentes son útiles; añadiendo a ellos:

Sí, NSUInteger da el doble de alcance entre los números enteros positivos como NSInteger, pero creo que otra de las razones fundamentales para elegir entre los dos es simplemente para distinguir entre los casos donde los valores negativos simplemente no tienen sentido.

Ejemplo: el valor de retorno de count método NSArray 's es un NSUInteger, lo cual tiene sentido ya que no podemos tener una matriz con un número negativo de elementos. Cuando el programador sabe que no está firmado, tiene más libertad para realizar operaciones que podrían no ser confiables en el caso firmado, incluidas las operaciones en modo bit, como el cambio. This blog post habla más sobre firmado vs sin firmar.

Mi conjetura sobre CGFloat vs NSFloat (que no existe): Podría ser el caso de que los diseñadores de los elementos de código con nombres NeXTStep simplemente no necesitan especificar demasiados valores de coma flotante, fuera del tiempo intervalos. Así que dieron NSTimeInterval, que es un tipo de coma flotante, pero que está claramente destinado a usarse con intervalos de tiempo. Y, francamente, es genial tener ese tipo porque sabes que siempre debe estar en segundos sin tener que lidiar con una estructura. Cuando te mueves al mundo de los gráficos (donde vive Core Graphics), de repente flotan a tu alrededor, flotando en el aire (jaja). Entonces tiene sentido presentar un CGFloat allí. Este párrafo es todo "especulación educada".

También, al igual que tener claro por las que podría utilizar NSInteger etc en lugar de tipos primitivos: Debido a que esta forma es más fácil escribir código portátil que aprovecha al máximo la arquitectura de la máquina. Por ejemplo, un CGFloat usa 32 bits en algunas máquinas y 64 bits en otras, dependiendo en gran medida de la brecha de eficiencia que exista en esas máquinas para esos tamaños. En algunos casos, no hay una aceleración real para usar 32 bits frente a 64 bits, por lo que también podría usar 64 bits. Si has declarado cosas como CGFloat, de repente obtienes esa precisión extra "gratis" cuando vuelvas a compilar.

Y, como iKenndac ha señalado, NSNumber Es una clase contenedora de todo de estos (y otros tipos primitivos o cuasi-primitivos como el BOOL) que le permite incluirlo en sus NSArray s y NSDictionary s, archívelos más fácilmente, y haga otras cosas que NSObject s puede hacer.

+0

Un punto realmente, realmente niggly: NSTimeinterval es un doble, no un flotador. Soy consciente de que el doble es la abreviatura de punto flotante de doble precisión, pero aún así. Además, entiendo que CGFloat compilando como un doble en 64 bits es genial, ¿pero NSInteger? No puedo pensar en una situación en la que eso sea útil. Diga en el código que está haciendo algunas operaciones matemáticas que requieren 64 bits ... no puede usar NSInteger si compila para 32. Si encaja en 32, ¿por qué usar 64? Parece extraño. – iKenndac

+1

Tienes razón, NSTimeInterval es un doble. Creo que todavía cuenta como un "tipo de coma flotante". Solo con doble precisión. También estoy de acuerdo en que en muchos casos una gran cantidad de código no mejorará al tener NSInteger convertido en 64 bits. Pero aquí hay una posibilidad: un generador de números aleatorios. En este caso, realmente le importa la velocidad, por lo que es posible que desee utilizar 32 bits cuando sea más rápido. Pero si 64 bits funcionan igual de bien, entonces de repente se obtiene un gran impulso en la felicidad aleatoria (_much_ longitud de ciclo más larga, etc.) sin mucho (si es que tiene alguno) costo de velocidad. – Tyler

+0

¿Por qué podemos votar una vez? ¡Brillante! –

56

NSNumber es una clase, no es una primitiva, y se utiliza cuando necesita poner números en bruto en diccionarios, matrices o encapsularlos de otra manera. NSInteger, NSUInteger, CGFloat, etc. son tipos simples y corresponden (en sistemas de 32 bits como el iPhone) a int, unsigned int y float.

Como regla general, si necesita almacenar un número en alguna parte, use NSNumber. Si está haciendo cálculos, bucles, etc., use NSInteger, NSUInteger o CGFloat.

Puedes envolver un NSInteger en un NSNumber:

NSNumber *aNumber = [NSNumber numberWithInteger:21]; 

... y recuperarlo:

NSInteger anInteger = [aNumber integerValue]; 

usted puede encontrar más información aquí: http://iosdevelopertips.com/cocoa/nsnumber-and-nsinteger.html

+0

Si el número nunca será negativo, ¿debería usar NSUInteger? – mk12

+0

¿Y cuál debería usar para un número con un decimal? – mk12

+0

¿Por qué es CGFloat y no NSFloat? – mk12

5

NSInteger es al igual que un int tradicional en C. Es un typedef. Hay otros como NSUInteger, CGFloat, etc. que son todos sinónimos de tipos primitivos.

NSNumber es útil cuando necesita insertar un número en un NSArray o NSDictionary. La práctica estándar es usar estas colecciones en comparación con las suyas propias; el inconveniente es que solo pueden contener objetos Objective-C.

NSNumber envuelve esencialmente un int (o flotador, etc) en un objeto Obj-C (similar al concepto C#/de Java de 'boxeo' un tipo primitivo) que se puede añadir a una matriz:

NSArray * myArray = [[NSArray alloc] init]; 
[myArray addObject:3]; // invalid, will not compile. 
[myArray [NSNumber numberWithInt:3]]; // ok 

Por razones de rendimiento, si puede, use tipos primitivos (como int, float, int []). Sin embargo, a veces no puede evitar NSArray/NSNumber, como cuando está leyendo o escribiendo entradas en un archivo .plist.

+1

NSInteger, NSUInteger y CGFloat son typedefs que son seguros por debajo de 32 o 64 bits. – Abizern

0

Como dijeron otros antes, NSNumber es una subclase NSObject. No es una primitiva C (como int, unsigned int, float, double, etc.) NSInteger, CGFloat, NSUInteger son simples typedefs sobre las primitivas C.

La necesidad de NSNumber surge de la necesidad de utilizar números como parámetros para las API que requieren Objetos. Ejemplo es cuando desea almacenar un número en un NSArray, en Core-Data, o en un NSDictionary.

¿Hay más primitivos como estos que deba conocer? Bueno, NSNumber no es un tipo primitivo, y envuelve todo tipo de números (flotantes, tipos integrales, booleanos, etc.). También debe conocer NSValue, que es la base para NSNumber.

¿Hay uno para flotadores? No hay ninguna typedef "NS" de flotador, pero NSNumber puede envolver alrededor de cualquier número de flotación:

NSNumber *myPi = [NSNumber numberWithFloat:3.1415926]; 

O usted podría utilizar los CoreGraphics tipo primitivo CGFloat.

2

NSNumber se utiliza generalmente para almacenar variables, NSUInteger se utiliza para la aritmética

puede cambiar una NSNumber a un NSUInteger al hacer esto:

NSNumber *variable = @1; 
NSUInteger variableInt = [variable unsignedIntegerValue]; 

Se ha dicho antes, pero como regla general de pulgar, las variables que deben definirse con * son clases Objective C, mientras que las variables que no necesitan a * son C primitivas.

Cuestiones relacionadas