XV. Chaînes▲
XV-A. Introduction▲
Jusqu'à présent, nous avons vu plusieurs types de données basiques : int, long, float, double, BOOL. Dans le précédent chapitre, nous avons introduit les pointeurs. Lorsque nous avons abordé le sujet des chaînes, nous n'en avons discuté que par rapport à la fonction NSLog(). Cette fonction nous a permis d'afficher une chaîne à l'écran, en remplaçant les codes commençant par un signe %, tel %d, par une valeur.
//[1]
float
Valeurpi =
3.1416
;
NSLog
(
@"Voici trois exemples de chaînes affichées à l'écran.
\n
"
);
NSLog
(
@"Pi se rapproche de %10.4f.
\n
"
, Valeurpi);
NSLog
(
@"Le nombre de faces d'un dé est %d.
\n
"
, 6
);
Nous n'avons pas parlé avant des chaînes en tant que types de données, pour une bonne raison. Contrairement aux entiers ou aux flottants, les chaînes sont de vrais objets, créés à l'aide de la classe NSString ou de la classe NSMutableString. Abordons ces classes, en commençant par NSString.
XV-B. NSString▲
XV-B-1. Encore les pointeurs▲
//[2]
NSString
*
favoriOrdinateur;
favoriOrdinateur =
@"Mac!"
;
NSLog
(
favoriOrdinateur);
Vous comprendrez sans doute la seconde déclaration, mais la première [2.1] mérite quelques explications. Vous vous souvenez que, lorsque nous avons déclaré une variable pointeur, nous avons dû indiquer sur quel type de données le pointeur devait pointer ? Voici une déclaration du chapitre 11 [3].
//[3]
int
*
y;
Ici on indique au compilateur que la variable pointeur y contient l'adresse d'un emplacement mémoire où un entier peut être trouvé.
Dans [2.1] nous disons au compilateur que la variable pointeur favoriOrdinateur contient l'adresse d'un emplacement mémoire où un objet de type NSString peut être trouvé. Nous utilisons un pointeur pour avoir prise sur notre chaîne, car en Objective-C les objets ne sont jamais manipulés directement, mais toujours au travers de pointeurs sur eux.
Ne vous inquiétez pas trop si vous ne comprenez pas totalement ce point ; il n'est pas essentiel. Ce qui est important, c'est de toujours se référer à une instance de NSString ou NSMutableString (ou bien sûr tout autre objet) en utilisant la notation *.
XV-B-2. Le symbole @▲
Bien, pourquoi est-ce que ce drôle de signe @ apparaît tout le temps ? Eh bien, Objective-C est une extension du langage C, qui a sa propre façon de traiter avec les chaînes. Pour différencier le nouveau type de chaînes, qui sont des objets à part entière, Objective-C utilise un signe @.
XV-B-3. Un nouveau type de chaîne▲
En quoi Objective-C améliore-t-il les chaînes du langage C ? Eh bien, les chaînes d'Objective-C sont des chaînes Unicode au lieu de chaînes ASCII. Les chaînes Unicode permettent d'afficher les caractères de presque toutes les langues, comme le chinois, aussi bien que l'alphabet Romain.
XV-C. Exercice▲
Bien sûr, il est possible de déclarer et initialiser la variable pointeur d'une chaîne d'un seul coup [4].
//[4]
NSString
*
favoriteActrice =
@"Julia"
;
La variable pointeur favoriteActrice pointe sur un emplacement mémoire où l'objet représentant la chaîne "Julia" est stockée.
Une fois que vous avez initialisé la variable, c'est-à-dire favoriOrdinateur, vous pouvez donner une autre valeur à la variable, mais vous ne pouvez pas changer la chaîne elle-même [5.7], car c'est une instance de la classe NSString. Plus de détails sur ce point dans une minute.
//[5]
#
import
<foundation/foundation.h>
int
main (
int
argc, const
char
*
argv[])
{
NSAutoreleasePool
*
pool =
[[NSAutoreleasePool
alloc] init];
NSString
*
favoriOrdinateur;
favoriOrdinateur =
@"iBook"
; // [5.7]
favoriOrdinateur =
@"MacBook Pro"
;
NSLog
(
@"%@"
, favoriOrdinateur);
[pool release];
return
0
;
}
Une fois exécuté, le programme affiche :
MacBook Pro
Quand on dit qu'une chaîne ne peut être modifiée, on peut quand même (et en fait on vient de le faire) remplacer la totalité de la chaîne par une autre chaîne.
XV-D. NSMutableString▲
Une chaîne de classe NSString est dite immuable, car elle ne peut être modifiée. Ce que nous entendons par là, c'est que les caractères individuels de la chaîne ne peuvent être modifiés.
À quoi bon une chaîne que vous ne pouvez modifier ? Eh bien, pour le système d'exploitation, les chaînes qui ne peuvent être modifiées sont plus faciles à gérer, donc votre programme pourra être plus rapide. En fait, lorsque vous utiliserez Objective-C pour écrire vos propres programmes, vous verrez que la plupart du temps, vous n'avez pas besoin de modifier vos chaînes.
Bien sûr, parfois vous aurez besoin de chaînes que vous pouvez modifier. Donc, il y a une autre classe, et les objets chaîne que vous créez avec elle sont modifiables. La classe à utiliser est NSMutableString. Nous en parlerons plus loin dans ce chapitre.
XV-E. Exercice▲
Tout d'abord, assurez-vous de bien comprendre que les chaînes sont des objets. Comme ce sont des objets, on peut leur envoyer des messages. Par exemple, nous pouvons envoyer le message longueur à un objet chaîne [6].
//[6]
#
import
<Foundation/Foundation.h>
int
main (
int
argc, const
char
*
argv[])
{
NSAutoreleasePool
*
pool =
[[NSAutoreleasePool
alloc] init];
int
laLongueur;
NSString
*
foo;
foo =
@"Julia !"
;
laLongueur =
[foo length]; // [6.10]
NSLog
(
@"La longueur est de %d."
, laLongueur);
[pool release];
return
0
;
}
Une fois exécuté, le programme affiche :
La longueur est de 7.
Les programmeurs utilisent souvent foo et bar comme noms de variables pour expliquer les choses. En fait ce sont de mauvais noms, parce qu'ils ne sont pas descriptifs, tout comme x. Nous vous les mettons ici afin que vous ne soyez pas étonné quand vous les verrez dans des discussions sur Internet.
En ligne [6.10], nous envoyons à l'objet foo, le message length (longueur). La méthode length est définie comme suit dans la classe NSString :
- (unsigned int)length
Retourne le nombre de caractères Unicode dans le destinataire.
Vous pouvez également mettre en majuscules les caractères de la chaîne [7]. À cette fin, envoyez à l'objet chaîne le message approprié, c'est-à-dire uppercaseString, que vous devriez être en mesure de trouver de par vous-même dans la documentation (examinez les méthodes disponibles dans la classe NSString). Dès réception de ce message, l'objet chaîne crée et retourne un nouvel objet chaîne ayant le même contenu, avec chaque caractère changé par sa valeur en majuscule correspondante.
//[7]
#
import
<Foundation/Foundation.h>
int
main (
int
argc, const
char
*
argv[])
{
NSAutoreleasePool
*
pool =
[[NSAutoreleasePool
alloc] init];
NSString
*
foo, *
bar;
foo =
@"Julia !"
;
bar =
[foo uppercaseString];
NSLog
(
@"%@ est converti en %@."
, foo, bar);
[pool release];
return
0
;
}
Une fois exécuté, le programme affiche :
Julia ! est converti en JULIA !.
Parfois, vous voudrez peut-être modifier le contenu d'une chaîne existante au lieu d'en créer une nouvelle. Dans ce cas, vous devrez utiliser un objet de classe NSMutableString pour représenter votre chaîne. NSMutableString fournit plusieurs méthodes qui vous permettent de modifier le contenu d'une chaîne. Par exemple, la méthode appendString: ajoute la chaîne passée comme argument à la fin du destinataire.
//[8]
#
import
<Foundation/Foundation.h>
int
main (
int
argc, const
char
*
argv[])
{
NSAutoreleasePool
*
pool =
[[NSAutoreleasePool
alloc] init];
NSMutableString
*
foo; // [8.7]
foo =
[@"Julia !"
mutableCopy]; // [8.8]
[foo appendString:@" Je suis heureux"
];
NSLog
(
@"Voici le résultat : %@."
, foo);
[pool release];
return
0
;
}
Une fois exécuté, le programme affiche :
">Voici le résultat : Julia ! Je suis heureux.
En ligne [8,8], la méthode mutableCopy (qui est fournie par la classe NSString) crée et retourne une chaîne mutable avec le même contenu que le destinataire. C'est-à-dire qu'après l'exécution de la ligne [8,8], foo pointe sur un objet chaîne mutable qui contient la chaîne "Julia !".
XV-F. Encore plus de pointeurs !▲
Plus avant dans ce chapitre nous avons déclaré que, en Objective-C, les objets ne sont jamais manipulés directement, mais toujours au travers de pointeurs sur eux. C'est pourquoi, par exemple, nous utilisons la notation du pointeur à la ligne [8.7] ci-dessus. En fait, lorsque nous utilisons le mot «objet» en Objective-C, ce que l'on veut généralement dire c'est "pointeur sur un objet". Mais puisque nous utilisons toujours les objets au travers des pointeurs, nous utilisons le mot «objet» comme raccourci. Le fait que les objets soient toujours utilisés au travers de pointeurs a une importante incidence que vous devez comprendre : plusieurs variables peuvent référencer le même objet en même temps. Par exemple, après exécution de la ligne [8.7], la variable foo référence un objet qui représente la chaîne "Julia !", quelque chose que nous pouvons représenter par l'illustration suivante :
Supposons maintenant que nous assignions la valeur de foo à la variable bar de cette façon :
bar =
foo;
Le résultat de cette opération est que, et foo et bar pointent maintenant sur le même objet :
Dans une telle situation, l'envoi d'un message à l'objet en utilisant foo comme destinataire (par exemple [foo faireqqchose];) a le même effet que l'envoi du message en utilisant bar (par exemple [bar faireqqchose];), comme montré dans cet exemple :
//[9]
#
import
<Foundation/Foundation.h>
int
main (
int
argc, const
char
*
argv[])
{
NSAutoreleasePool
*
pool =
[[NSAutoreleasePool
alloc] init];
NSMutableString
*
foo =
[@"Julia !"
mutableCopy];
NSMutableString
*
bar =
foo;
NSLog
(
@"foo pointe sur la chaîne : %@."
, foo);
NSLog
(
@"bar pointe sur la chaîne : %@."
, bar);
NSLog
(
@"
\n
"
);
[foo appendString:@" Je suis heureux"
];
NSLog
(
@"foo pointe sur la chaîne : %@."
, foo);
NSLog
(
@"bar pointe sur la chaîne : %@."
, bar);
[pool release];
return
0
;
}
Une fois exécuté, le programme affiche :
foo pointe sur la chaîne : Julia !
bar pointe sur la chaîne : Julia !
foo pointe sur la chaîne : Julia ! Je suis heureux
bar pointe sur la chaîne : Julia ! Je suis heureux
Être capable d'avoir des références sur le même objet depuis différents endroits en même temps est une caractéristique essentielle des langages orientés-objets. En fait, nous l'avons déjà utilisée dans les précédents chapitres. Par exemple, au chapitre 8, nous avons référencé notre objet MAFoo depuis deux objets bouton différents.