Haciendo una matriz de enteros en iOS

98

Si desea hacer una matriz de números enteros, ¿puede usar NSInteger? ¿Tiene que usar NSNumber? Si es así, ¿por qué?

neuromante
fuente
¿Qué quieres hacer con tu matriz de números enteros?
dreamlax
No estoy seguro. Escuché en algún lugar que tienes que usar NSNumber para matrices y me preguntaba sobre eso.
neuromante

Respuestas:

159

Puede usar una matriz C simple y antigua:

NSInteger myIntegers[40];

for (NSInteger i = 0; i < 40; i++)
    myIntegers[i] = i;

// to get one of them
NSLog (@"The 4th integer is: %d", myIntegers[3]);

O puede usar una NSArrayo NSMutableArray, pero aquí deberá envolver cada entero dentro de una NSNumberinstancia (porque los NSArrayobjetos están diseñados para contener instancias de clases).

NSMutableArray *myIntegers = [NSMutableArray array];

for (NSInteger i = 0; i < 40; i++)
    [myIntegers addObject:[NSNumber numberWithInteger:i]];

// to get one of them
NSLog (@"The 4th integer is: %@", [myIntegers objectAtIndex:3]);

// or
NSLog (@"The 4th integer is: %d", [[myIntegers objectAtIndex:3] integerValue]);
Dreamlax
fuente
9
Creo que vale la pena señalar que las matrices C son tan complicadas para cualquier uso que no sea trivial y único, que en realidad es menos problemático envolver las matrices que planea mantener como NSArrays de NSNumber.
Chuck
2
Sí, y dadas las optimizaciones de nivel experto [presumiblemente] bajo el capó de NSArray, estoy seguro de que no sentirás el impacto en el rendimiento.
dreamlax
@dreamlax Me pregunto qué tipo de optimización de nivel experto hay bajo el capó de NSArray. ¿Asignación de memoria inteligente que simplemente probablemente duplica el tamaño de la memoria asignada una vez que alcanza el límite? :) p
Ben Sinclair
2
@Andy: Eche un vistazo a la fuente real de CFArray aquí y consulte los puntos de referencia aquí . Es un poco más inteligente de lo que piensas inicialmente.
dreamlax
Suponiendo que esta matriz solo se usa dentro de un método, ¿no hay problemas con el uso de una matriz C de NSIntegers? Solo verifica dos
veces
58

Matriz C:

NSInteger array[6] = {1, 2, 3, 4, 5, 6};

Matriz Objective-C:

NSArray *array = @[@1, @2, @3, @4, @5, @6];
// numeric values must in that case be wrapped into NSNumbers

Matriz veloz:

var array = [1, 2, 3, 4, 5, 6]

Esto también es correcto:

var array = Array(1...10)

NB: las matrices están fuertemente tipadas en Swift; en ese caso, el compilador infiere del contenido que la matriz es una matriz de enteros. También puede usar esta sintaxis de tipo explícito:

var array: [Int] = [1, 2, 3, 4, 5, 6]

Si quisiera una matriz de dobles, usaría:

var array = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0] // implicit type-inference

o:

var array: [Double] = [1, 2, 3, 4, 5, 6] // explicit type
Frédéric Adda
fuente
1
¿Cuál sería la sintaxis "@number" equivalente para un entero negativo?
Ziofil
5

Si desea utilizar un NSArray, necesita una clase Objective-C para colocarlo, de ahí el requisito NSNumber.

Dicho esto, Obj-C sigue siendo C, por lo que puede usar matrices C regulares y mantener entradas regulares en lugar de NSNumbers si es necesario.

Dennis Munsie
fuente
4

Puede utilizar CFArray en lugar de NSArray. Aquí hay un artículo que explica cómo.

CFMutableArrayRef ar = CFArrayCreateMutable(NULL, 0, NULL);
for (NSUInteger i = 0; i < 1000; i++)
{
  CFArrayAppendValue(ar, (void*)i);
}
CFRelease(ar); /* Releasing the array */

Lo mismo se aplica a la versión CoreFoundation de los otros contenedores también.

coyotte508
fuente
3
Si hay una ventaja de usar CFArray sobre NSArray, no la veo. Un NSArray ES un CFArray debajo del capó; esto es hacerlo de la manera difícil.
David Gish
1
@Cryptognome hay una pequeña diferencia aquí, CFArray no retendrá ni publicará nada porque se creó sin devoluciones de llamada. Sin embargo, estoy de acuerdo, no parece haber ninguna ventaja.
dreamlax
3

Si no se requiere el orden de sus números enteros y si solo hay valores únicos

también puede usar NSIndexSet o NSMutableIndexSet Podrá agregar y eliminar enteros fácilmente, o verificar si su matriz contiene un entero con

- (void)addIndex:(NSUInteger)index
- (void)removeIndex:(NSUInteger)index
- (BOOL)containsIndexes:(NSIndexSet *)indexSet

Consulte la documentación para obtener más información.

didier_v_
fuente
2
Esa es una idea terrible. Aquí hay un fragmento de la documentación de Apple: No debe usar conjuntos de índices para almacenar una colección arbitraria de valores enteros porque los conjuntos de índices almacenan índices como rangos ordenados. Esto los hace más eficientes que almacenar una colección de enteros individuales. También significa que cada valor de índice solo puede aparecer una vez en el conjunto de índices.
Rudolf Adamkovič
1
Estoy de acuerdo y es por eso que comencé mi respuesta con una advertencia. Sin embargo, conozco a algunas personas que han hecho esta pregunta sobre matrices de números enteros y, de hecho, necesitan un conjunto de índices. Por eso di esta respuesta alternativa.
didier_v_
¿Qué tiene de malo solo un regular NSSet(y usar enteros envueltos en un NSNumber)?
Dreamlax
@dreamlax sobrecarga, pero en general, las personas que hacen estas preguntas no pueden manejar C y simplemente tienen pocos números para almacenar, por lo que NSArray o NSSet deben ser los mejores.
Ben Sinclair
2

Creo que es mucho más fácil usar NSNumbers. Esto es todo lo que necesitas hacer:

NSNumber *myNum1 = [NSNumber numberWithInt:myNsIntValue1];
NSNumber *myNum2 = [NSNumber numberWithInt:myNsIntValue2];
.
.
.
NSArray *myArray = [NSArray arrayWithObjects: myNum1, myNum2, ..., nil];
Neeku
fuente
pero ¿qué pasa si su matriz tiene 10 o 100 números?
Henson
1
Puede usar foro simplemente otra matriz para los números, y luego arrayWithArray.
Neeku