XVI. Tableaux▲
XVI-A. Introduction▲
Parfois vous aurez à organiser des collectes de données. Vous pourrez, par exemple, devoir entretenir une liste de chaînes. Il serait assez encombrant d'utiliser une variable pour chacune de ces chaînes. Bien sûr, il existe une solution plus pratique : le tableau.
Un tableau est une liste ordonnée d'objets (ou, plus exactement, une liste de pointeurs sur des objets). Vous pouvez ajouter des objets dans un tableau, les supprimer, ou demander au tableau de vous indiquer quel objet est stocké à un index donné (c'est-à-dire, à une position donnée). Vous pouvez également demander au tableau de vous indiquer le nombre d'éléments qu'il contient.
Lorsque vous comptez des articles, vous commencez habituellement en partant de 1. Toutefois, dans les tableaux, le premier article est à l'index 0, le deuxième à l'index 1 et ainsi de suite.
Plus loin dans ce chapitre, nous vous donnerons un exemple de code vous permettant de voir la conséquence du fait de compter à partir de 0.
Les tableaux sont fournis par deux classes : NSArray et NSMutableArray. Comme pour les chaînes, il existe une version immuable et une mutable. Dans ce chapitre, nous étudierons la version mutable.
Ce sont des tableaux spécifiques à Objective-C et Cocoa. Il existe un autre type de tableau, plus simple, en langage C (qui fait donc aussi partie d'Objective-C), mais nous n'en parlerons pas ici. Ceci n'est juste qu'un rappel sur ce que vous pourrez lire ailleurs plus tard sur les tableaux C, et comprenez bien qu'ils n'auront pas grand-chose à faire avec NSArray ou NSMutableArray.
XVI-B. Une méthode de classe▲
Une façon de créer un tableau est d'exécuter une expression comme celle-ci :
[NSMutableArray
tableau];
Une fois évalué, ce code crée et retourne un tableau vide. Mais... attendez une minute... ce code semble étrange, non ? En effet, dans ce cas nous avons utilisé le nom de la classe NSMutableArray pour spécifier le destinataire d'un message. Mais jusqu'à présent, nous n'avons envoyé des messages qu'à des instances, pas à des classes, d'accord ?
Eh bien, nous venons d'apprendre quelque chose de nouveau : le fait que, en Objective-C, nous pouvons aussi envoyer des messages aux classes (et la raison en est que les classes sont aussi des objets, instances de ce que l'on appelle des métaclasses, mais nous n'explorerons pas plus avant cette idée dans ce papier introductif).
Il conviendra de noter que cet objet est automatiquement autoreleased (auto-libéré) lors de sa création, c'est-à-dire qu'il est attaché à un NSAutoreleasePool et voué à la destruction par la méthode de classe qui l'a créé. Appeler la méthode de classe est équivalent à :
NSMutableArray
*
tableau =
[[[NSMutableArray
alloc] init] autorelease];
Dans l'éventualité où vous souhaitez que le tableau persiste plus longtemps que la durée de vie du pool autorelease, vous devez envoyer un message -retain à l'instance.
Dans la documentation Cocoa, les méthodes qui nous permettent d'appeler des classes sont signalées par un symbole «+», au lieu du symbole "-" que nous voyons habituellement devant le nom des méthodes (voir exemple au chapitre 8 [4.5]). Par exemple, dans la documentation, nous voyons cette description pour la méthode tableau :
array
+ (id)array
Crée et retourne un tableau vide. Cette méthode est utilisée par les sous-classes mutables de NSArray. Voir aussi: + arrayWithObject:, + arrayWithObjects:.
XVI-C. Exercice▲
Revenons au codage. Le programme suivant crée un tableau vide, y stocke trois chaînes, puis affiche le nombre d'éléments du tableau.
//[1]
#
import
<foundation/foundation.h>
int
main (
int
argc, const
char
*
argv[])
{
NSAutoreleasePool
*
pool =
[[NSAutoreleasePool
alloc] init];
NSMutableArray
*
monTableau =
[NSMutableArray
tableau];
[monTableau addObject:@"première chaîne"
];
[monTableau addObject:@"deuxième chaîne"
];
[monTableau addObject:@"troisième chaîne"
];
int
count =
[monTableau count];
NSLog
(
@"Il y a %d éléments dans mon tableau"
, count);
[pool release];
return
0
;
}
Une fois exécuté, le programme affiche :
Il y a 3 éléments dans mon tableau
Le programme suivant est la même que le précédent sauf qu'il affiche la chaîne stockée à l'index 0 du tableau. Pour atteindre cette chaîne, il utilise la méthode objectAtIndex: [2.13].
//[2]
#
import
<foundation/foundation.h>
int
main (
int
argc, const
char
*
argv[])
{
NSAutoreleasePool
*
pool =
[[NSAutoreleasePool
alloc] init];
NSMutableArray
*
monTableau =
[NSMutableArray
tableau];
[monTableau addObject:@"première chaîne"
];
[monTableau addObject:@"deuxième chaîne"
];
[monTableau addObject:@"troisième chaîne"
];
NSString
*
élément =
[monTableau objectAtIndex:0
]; // [2.13]
NSLog
(
@"L'élément à l'index 0 du tableau est : %@"
, élément);
[pool release];
return
0
;
}
Une fois exécuté, le programme affiche :
L'élément à l'index 0 du tableau est : première chaîne
Vous devrez souvent parcourir un tableau pour faire quelque chose avec chacun de ses éléments. Pour ce faire, vous pouvez utiliser une boucle comme dans le programme suivant qui affiche chaque élément du tableau avec son index :
//[3]
#
import
<foundation/foundation.h>
int
main (
int
argc, const
char
*
argv[])
{
NSAutoreleasePool
*
pool =
[[NSAutoreleasePool
alloc] init];
NSMutableArray
*
monTableau =
[NSMutableArray
tableau];
[monTableau addObject:@"première chaîne"
];
[monTableau addObject:@"deuxième chaîne"
];
[monTableau addObject:@"troisième chaîne"
];
int
i;
int
count;
for
(
i =
0
, count =
[monTableau count]; i <
count; i =
i +
1
)
{
NSString
*
élément =
[monTableau objectAtIndex:i];
NSLog
(
@"L'élément à l'index %d du tableau est : %@"
, i, élément);
}
[pool release];
return
0
;
}
Une fois exécuté, le programme affiche :
L'élément à l'index 0 du tableau est : première chaîne
L'élément à l'index 1 du tableau est : deuxième chaîne
L'élément à l'index 2 du tableau est : troisième chaîne
Notez que les tableaux ne sont pas limités aux chaînes. Ils peuvent contenir tout objet que vous voulez.
Les classes NSArray et NSMutableArray fournissent de nombreuses autres méthodes, et vous êtes encouragé à consulter la documentation de ces classes afin d'en apprendre davantage sur les tableaux. Nous allons finir chapitre en parlant de la méthode qui vous permet de remplacer un objet d'un index donné par un autre objet. Cette méthode se nomme replaceObjectAtIndex:withObject:.
Jusqu'à présent nous n'avons traité qu'avec des méthodes ne prenant au plus qu'un argument. Celle-ci est différente, et c'est pourquoi nous allons l'examiner ici : elle prend deux arguments. Vous pouvez le dire, car son nom contient deux deux-points. En Objective-C, les méthodes peuvent avoir un nombre quelconque d'arguments. Voici comment vous pouvez utiliser cette méthode :
//[4]
[monTableau replaceObjectAtIndex:1
withObject:@"Bonjour"
];
Après l'exécution de cette méthode, l'objet à l'index 1 est la chaîne @"Bonjour". Bien entendu, cette méthode ne doit être invoquée qu'avec un index valable. C'est-à-dire qu'il faut déjà avoir un objet stocké à l'index que nous donnons à la méthode, afin que la méthode soit en mesure de le remplacer dans le tableau par l'objet que nous passons.
XVI-D. Conclusion▲
Comme vous pouvez le voir, les noms de méthode en Objective-C sont comme des phrases avec des trous dedans (préfixés par des virgules). Lorsque vous invoquez une méthode, vous remplissez les trous avec de vraies valeurs, créant une "phrase" sensée. Cette façon de désigner les noms de méthode et l'invocation de la méthode vient de Smalltalk et est l'une des plus grandes forces d'Objective-C, car il rend le code très expressif. Lorsque vous créerez vos propres méthodes, vous devrez vous efforcer de les nommer de façon à ce qu'elles forment des phrases expressives en cas d'appel. Cela aide à rendre lisible le code Objective-C, ce qui est très important pour une maintenance plus aisée de vos programmes.