Bonjour !
Bienvenue dans ce cinquième tutoriel version 2 !
Aujourd'hui, nous allons apprendre à nous servir des Tableaux. Il en existe deux sortes : les objets NSArray et NSMutableArray. La principale différence est simple : un NSArray a une taille fixe, tandis qu'un NSMutableArray n'a pas de taille définie. C'est-à-dire qu'on pourrait lui ajouter des éléments "indéfiniment".
Pour la petite histoire, on parle de tableaux "statiques" pour les NSArray, et "dynamiques" pour les NSMutableArray.
Pour les tableaux, étant donné que l'Objective-C vient du C, vous pouvez déclarer des tableaux comme ceci
// petit rappel : char tableau[10]; //tableau de 10 caractères int tableau2[10][10]; // tableau bidimensionnel d'entiers soit 100 entiers
Du coup, ce type de déclaration s'apparente aux NSArray, car leur taille est fixe.
Nous allons donc nous intéresser aux NSMutableArray :
1) Créons notre projet ainsi que l'interface
Créez un projet "Window-based application" que vous nommerez iPuPArray
Commencez par créer une interface comme dans le tutoriel n°3.
La première astuce du tutoriel : faites un tour ici sous IB

Vous verrez que vous pouvez ajouter des lignes horizontales et verticales rouges pour vous aider à agencer vos objets.
2) Ecrivons un peu de code ...
Une fois tout relié et la classe écrite dans XCode, nous allons modifier les fichiers "iPuPView.m" et "iPuPView.h". Double-cliquez sur "iPuPView.m".
La deuxième astuce du jour : en haut à droite de votre fenêtre, vous allez trouver une petite icône ressemblant à ceci :

Cliquez-dessus...
vous passez au header! Recliquez...
retour au .m!
Bon, il suffit, on n'est pas là pour jongler entre les fenêtres, vous voulez faire des tableaux ou pas? 
Voici ce que nous allons faire : créer une méthode qui permettra de créer un tableau et l'exporter dans un fichier texte .txt. Nous la nommerons "createAnArrayAndExportToTextFile" ... Bon, cela fait des noms à rallonge, mais vous savez de quoi vous parlez après 
Ensuite, nous allons créer une méthode qui se chargera d'afficher le contenu du tableau dans le label. Nous verrons la description de la méthode plus tard...
Commençons par la méthode "createAnArrayAndExportToATextFile"
Tout d'abord, écrivez ceci dans l'implementation de iPuPView (Rappel : dans le "iPuPView.m")
// Permet de créer un tableau et de l'exporter dans un fichier texte
- (BOOL) createAnArrayAndExportToTextFile {
}Nous allons maintenant créer un NSMutableArray en l'initialisant avec des objets NSString :
// créé un NSMutableArray et l'initialise avec @"Object 1", @"Object 2", @"Object 3" NSMutableArray *iPuPArray = [[NSMutableArray alloc] initWithObjects:@"Object 1", @"Object 2", @"Object 3",nil];
N'oubliez pas de terminer par nil...
Il faut ensuite écrire ce tableau dans le fichier "iPuP.txt"
Attention, il faut bien utiliser le dossier "Documents" de l'application dans votre iPhone. C'est le seul endroit où votre application aura le droit d'écrire.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@"nomFichier.txt"];D'où :
Un peu de culture, mais pas obligatoire : 
Si "atomically" est à NO, cela signifie que vous écrivez directement dans le fichier "iPuP.txt". Si il est à YES, l'écriture se fait déjà dans un fichier temporaire, puis dans le fichier texte.
Ok... "Si tu veux" me direz-vous. Eh bien, le fait de mettre à YES permet de ne pas corrompre le fichier texte si votre appli crashe pendant l'écriture... voilà 
Très bien! vous vous en doutez, il faut maintenant faire un ........... pour iPuPArray ? ............. un ...... release Oui! N'oubliez jamais : après un alloc, un release! Ici, nous utilisons un mécanisme particulier : l'autorelease. Lisez la "fiche mémoire" !
// permet de libérer automatiquement de la mémoire iPuPArray
[iPuPArray autorelease];Récapitulons : votre méthode ressemble à ça :
// Permet de créer un tableau et de l'exporter dans un fichier texte
// Permet de créer un tableau et de l'exporter dans un fichier texte
- (BOOL) createAnArrayAndExportToTextFile {
// créé un NSMutableArray et l'initialise avec @"Object 1", @"Object 2", @"Object 3"
NSMutableArray *iPuPArray = [[NSMutableArray alloc] initWithObjects:@"Object 1", @"Object 2", @"Object 3",nil];
// exporte le contenu du tableau dans un fichier txt
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@"iPuP.txt"];
// permet de libérer automatiquement de la mémoire iPuPArray
[iPuPArray autorelease];
// ecrit dans le fichier et retourne un booléen
return [iPuPArray writeToFile:filePath atomically:YES] && filePath;
}Ok, <pomme + s> et cliquez sur notre bouton du jour :

. Dans le header, "iPuPView.h", écrivez ceci
- (BOOL) createAnArrayAndExportToTextFile;
Euh, pourquoi ce n'est pas -(void) maMethode, mais -(BOOL) maMethode ?? !
Tout simplement parce que nous souhaitons savoir si l'écriture dans le fichier s'est bien passée et si le fichier existe bien.
Or la doc nous dit :
Donc, si le tableau est bien écrit, la méthode retournera YES !
Deuxième étape : afficher un élément du tableau dans un label...
Mais il faut bien comprendre comment accéder aux données de votre tableau.
En fait, vos objets dans le tableau sont indexés.
En C, rappelez-vous, vous accédiez aux éléments de "tableau" de la sorte :
int tableau[3]; int element; tableau[0]=4; tableau[1]=8; tableau[2]=16; element = tableau[0]; // element sera donc égal à la première valeur de votre tableau soit 4
Avec un NSArray, c'est la même chose, on accède à l'élément i avec "atIndex:i"
Revenez à votre .m et écrivons notre méthode displayElementOfArray :
Nous allons faire passer des paramètres à cette méthode. Soyez attentifs à l'écriture.
// permet d'afficher l'élément à l'index "index" d'un tableau passé en paramètre dans un label
- (void) displayElementOfArray:(NSArray *) monTableau forIndex:(NSInteger) index {
}Pour afficher l'élément de l'index dans votre label :
//affiche le texte de l'objet du tableau à l'index spécifié monLabel.text = [monTableau objectAtIndex:index]; // Attention : ici, si index est plus grand que la taille de notre tableau, l'appli plante. // On peut implémenter une fonction gérant "si index>taille de monTableau alors on ne fait rien sinon on affiche"
N'oubliez pas de mettre la fonction dans le .h.
Finalement,
// permet d'afficher l'élément à l'index "index" d'un tableau passé en paramètre dans un label
- (void) displayElementOfArray:(NSArray *) monTableau forIndex:(NSInteger) index {
if(index < [monTableau count])
{
NSLog(@"L'index %d est ok, on affiche dans le label", index);
//affiche le texte de l'objet du tableau à l'index spécifié
labeliPuP.text = [monTableau objectAtIndex:index];
}
else
{
NSLog(@"L'index %d est en dehors du tableau, erreur", index);
labeliPuP.text = @"Erreur";
}
[labeliPuP sizeToFit];
}3) Utilisons tout ça
Pour terminer, il faut créer ce tableau et afficher un élément. Pour l'instant, nous n'avons qu'écris les méthodes permettant de le faire.
Pour cela, nous allons utiliser encore awakeFromNib. Sachez juste que nous utilisons cette méthode pour le besoin du tutoriel. Nous souhaitons simplement vous montrer comment fonctionne les tableaux sans gérer d'événements.
- (void) awakeFromNib {
[labeliPuP setTextColor:[UIColor colorWithRed:200.0/255.0 green:250.0/255.0 blue:255.0/255.0 alpha:1.0]];
[labeliPuP setFont:[UIFont fontWithName:@"Zapfino" size:19.0]];
// on recherche le filePath
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@"iPuP.txt"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSData *data = [fileManager contentsAtPath:filePath];
BOOL peutLireDansLeFichier = NO;
if(!data)
{
// le fichier iPuP.txt ne contient aucune donnée, il nous faut donc le remplir pour les besoins du tuto :
//crée un tableau et l'exporte dans un fichier texte
BOOL success = [self createAnArrayAndExportToTextFile];
NSLog(@"Création d'un array = succès ? %@", success ? @"YES" : @"NO");
peutLireDansLeFichier = success;
}
else
{
// le fichier contient déjà des données, donc on peut lire sans souci dedans !
peutLireDansLeFichier = YES;
}
if(peutLireDansLeFichier)
{
NSLog(@"Le fichier contient des données, on peut lire dedans");
//création d'un NSArray qui lira dans le fichier Texte (initialisation avec
// le contenu d'un fichier : iPuP.txt dont nous avons spécifié le chemin avec filePath
NSArray *iPuPArray = [[NSArray alloc] initWithContentsOfFile:filePath];
//appel de la fonction permettant l'affichage dans le label
[self displayElementOfArray:iPuPArray forIndex:3];
// libére la mémoire
[iPuPArray release];
}
}Sauvez et lancez. Vous obtenez ceci :

Vous avez bien affiché le troisième élément de votre tableau! Ouf... 
Amusez à vous changer la valeur de l'index lors de l'appel de displayElementOfArray.
Voilà, vous savez comment utiliser un tableau!
4) Allons plus loin ...
Vous pouvez ajoutez un élément dans votre NSMutableArray de la manière suivante :
// ajoute un élément dans le tableau [iPuPArray addObject:@"iPuP"];
soit
// Permet de créer un tableau et de l'exporter dans un fichier texte
- (BOOL) createAnArrayAndExportToTextFile {
// créé un NSMutableArray et l'initialise avec @"Object 1", @"Object 2", @"Object 3"
NSMutableArray *iPuPArray = [[NSMutableArray alloc] initWithObjects:@"Object 1", @"Object 2", @"Object 3",nil];
// ajoute un élément dans le tableau
[iPuPArray addObject:@"iPuP"];
// exporte le contenu du tableau dans un fichier txt
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@"iPuP.txt"];
// permet de libérer automatiquement de la mémoire iPuPArray
[iPuPArray autorelease];
// ecrit dans le fichier et retourne un booléen
return [iPuPArray writeToFile:filePath atomically:YES] && filePath;
}Maintenant, affichez l'élément 4 (atIndex:3 (4-1))
//appel de la méthode permettant l'affichage dans le label [self displayElementOfArray:iPuPArray forIndex:3];
Vous obtenez

Pour aller encore plus loin...
Si vous utilisiez des tableaux bidimensionnels, vous pourriez accéder à l'élément de la colonne j et ligne i, en représentation matricielle, par "tableau [i][j]". Rappelez vous, les lignes et colonnes commencent à 0 et pas à 1.
Vous pouvez continuer à utiliser des NSArray ou NSMutableArray qui sont des tableaux à une dimension de la manière suivante : connaissant le nombre de colonnes m de votre tableau bidimensionnel, l'élément de la ligne i et colonne j est accessible à l'index suivant : k=i*m+j.
Cela peut se révéler utile si vous souhaitez mettre des objets dans un tableau, plus compliqués qu'un NSString.
sources
Petit exercice
Ajouter un textField à votre view, autoriser les interactions pour cette vue si besoin (cocher "User Interaction Enabled")

Il vous faudra aller chercher dans les propriétés du textField pour que "Enter" soit "Done", mettre par défaut un clavier numérique, ...
Aide et correction
Voilà, à bientôt dans un prochain tutoriel!
Ipodishima
Copyright © 2009 - ipup.fr • création de Jérémy Lagrue • design de Loann Fraillon • contact