Créer un tableau d'entiers sous iOS

98

Si vous souhaitez créer un tableau d'entiers, pouvez-vous utiliser NSInteger? Devez-vous utiliser NSNumber? Si oui, pourquoi?

neuromancien
la source
Que voulez-vous faire avec votre tableau d'entiers?
dreamlax
Pas certain. Je viens d'entendre quelque part que vous devez utiliser NSNumber pour les tableaux et je me posais des questions à ce sujet.
neuromancer

Réponses:

159

Vous pouvez utiliser un ancien tableau C simple:

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]);

Ou, vous pouvez utiliser un NSArrayou NSMutableArray, mais ici vous devrez encapsuler chaque entier dans une NSNumberinstance (car les NSArrayobjets sont conçus pour contenir des instances de classe).

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
la source
9
Je pense qu'il vaut la peine de noter que les tableaux C sont si compliqués pour tout sauf une utilisation triviale et ponctuelle qu'il est en fait moins difficile d'envelopper les tableaux que vous prévoyez de conserver en tant que NSArrays de NSNumber.
Chuck
2
Oui, et étant donné les optimisations [vraisemblablement] de niveau expert sous le capot de NSArray, je suis sûr que vous ne sentirez pas la performance frapper.
dreamlax
@dreamlax Je me demande quel type d'optimisation de niveau expert est sous le capot de NSArray? Allocation de mémoire intelligente qui double probablement la taille de la mémoire allouée une fois qu'elle atteint la limite?
Ben Sinclair
2
@Andy: Jetez un œil à la source réelle de CFArray ici et consultez les benchmarks ici . C'est un peu plus intelligent que vous ne le pensez au départ.
dreamlax
En supposant que ce tableau est juste utilisé dans une méthode, il n'y a aucun problème avec l'utilisation d'un tableau C de NSIntegers? Juste une double vérification ...
Dan Rosenstark
58

Tableau C:

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

Tableau Objective-C:

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

Réseau rapide:

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

Ceci est également correct:

var array = Array(1...10)

NB: les tableaux sont fortement typés en Swift; dans ce cas, le compilateur déduit du contenu que le tableau est un tableau d'entiers. Vous pouvez également utiliser cette syntaxe de type explicite:

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

Si vous vouliez un tableau de doubles, vous utiliseriez:

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

ou:

var array: [Double] = [1, 2, 3, 4, 5, 6] // explicit type
Frédéric Adda
la source
1
Quelle serait la syntaxe équivalente "@number" pour un entier négatif?
Ziofil le
5

Si vous souhaitez utiliser un NSArray, vous avez besoin d'une classe Objective-C pour y mettre - d'où l'exigence NSNumber.

Cela dit, Obj-C est toujours C, vous pouvez donc utiliser des tableaux C normaux et contenir des entiers normaux au lieu de NSNumbers si vous en avez besoin.

Dennis Munsie
la source
4

Vous pouvez utiliser CFArray au lieu de NSArray. Voici un article expliquant comment.

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

Il en va de même pour la version CoreFoundation des autres conteneurs.

coyotte508
la source
3
S'il y a un avantage à utiliser CFArray sur NSArray, je ne le vois pas. Un NSArray EST un CFArray sous le capot; c'est juste le faire à la dure.
David Gish
1
@Cryptognome il y a une petite différence ici, le CFArray ne retiendra ni ne libérera rien car il a été créé sans callback. Je suis d'accord cependant, il ne semble y avoir aucun avantage.
dreamlax
3

Si l'ordre de vos entiers n'est pas requis, et s'il n'y a que des valeurs uniques

vous pouvez également utiliser NSIndexSet ou NSMutableIndexSet Vous pourrez facilement ajouter et supprimer des entiers, ou vérifier si votre tableau contient un entier avec

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

Consultez la documentation pour plus d'informations.

didier_v_
la source
2
C'est une idée terrible. Voici un extrait de la documentation d'Apple: vous ne devez pas utiliser d'ensembles d'index pour stocker une collection arbitraire de valeurs entières car les ensembles d'index stockent les index sous forme de plages triées. Cela les rend plus efficaces que le stockage d'une collection d'entiers individuels. Cela signifie également que chaque valeur d'index ne peut apparaître qu'une seule fois dans l'ensemble d'index.
Rudolf Adamkovič
1
Je suis d'accord et c'est pourquoi j'ai commencé ma réponse par un avertissement. Cependant, je connais des personnes qui ont posé cette question sur les tableaux d'entiers et qui avaient en fait besoin d'un ensemble d'index. C'est pourquoi j'ai donné cette réponse alternative.
didier_v_
Quel est le problème avec juste un régulier NSSet(et l'utilisation d'entiers enveloppés dans un NSNumber)?
dreamlax
@dreamlax overhead, mais en général, les personnes qui posent de telles questions ne peuvent pas gérer C et elles ont simplement peu de numéros à stocker, donc NSArray ou NSSet doivent être les meilleurs.
Ben Sinclair
2

Je pense que c'est beaucoup plus facile d'utiliser NSNumbers. Voici tout ce que vous devez faire:

NSNumber *myNum1 = [NSNumber numberWithInt:myNsIntValue1];
NSNumber *myNum2 = [NSNumber numberWithInt:myNsIntValue2];
.
.
.
NSArray *myArray = [NSArray arrayWithObjects: myNum1, myNum2, ..., nil];
Neeku
la source
mais que faire si votre tableau a 10 ou 100 nombres?
Henson
1
Vous pouvez utiliser forou simplement un autre tableau pour les nombres, puis arrayWithArray.
Neeku