8
3 Objective-C Il était une fois un homme, nommé Brad Cox, qui avait décidé que le monde devait passer à un style de programmation plus modulaire. Le langage C était répandu et puissant. Smalltalk était un langage orienté objet, non typé et élégant. Brad Cox a introduit dans C les mécanismes de classes et d’envoi de messages de Smalltalk. Le résultat, Objective-C, est une extension très simple du langage C. En réalité, Objective-C était à l’origine un simple préprocesseur C et une bibliothèque. Objective-C n’est pas un langage propriétaire. Il s’agit d’un standard ouvert qui existe depuis des années dans le compilateur GNU C (gcc) de la FSF (Free Software Foundation). Plus récemment, Apple s’est fortement impliqué dans les projets de compilateurs open-source clang/ LLVM (Low Level Virtual Machine ), qui sont plus rapides et plus polyvalents que gcc. Dans les projets Xcode, LLVM est le compilateur par défaut. Cocoa a été développé à partir d’Objective-C, et la programmation Cocoa se fait généra- lement en Objective-C. Pour enseigner le langage C et les concepts de base de l’orienté objet, il faudrait un livre complet. Ce chapitre suppose que vous avez déjà quelques notions de C et de la programmation orientée objet et présente les bases d’Objective-C. Si vous correspondez à ce profil, vous constaterez que l’apprentissage d’Objective-C est facile. Dans le cas contraire, l’ouvrage The Objective-C Language d’Apple ou notre livre Programmation Objective-C, Le guide Big Nerd Ranch seront de bonnes introductions. Créer et utiliser des instances Au Chapitre 1, nous avons indiqué que les classes servaient à créer des objets, que les objets avaient des méthodes et qu’il était possible d’envoyer des messages aux objets pour déclencher l’invocation des méthodes. Dans cette section, vous allez apprendre à créer un objet et à lui envoyer des messages. © 2013 Pearson France – Programmation Cocoa sous Mac OS X – Aaron Hillegass, Adam Preble

Programmation Cocoa sous Mac OS X - 4e édition - Le guide ... · LLVM (Low Level Virtual Machine), qui sont plus rapides et plus polyvalents que gcc. Dans les projets Xcode, LLVM

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Programmation Cocoa sous Mac OS X - 4e édition - Le guide ... · LLVM (Low Level Virtual Machine), qui sont plus rapides et plus polyvalents que gcc. Dans les projets Xcode, LLVM

3Objective-CIl était une fois un homme, nommé Brad Cox, qui avait décidé que le monde devait passer à un style de programmation plus modulaire. Le langage C était répandu et puissant. Smalltalk était un langage orienté objet, non typé et élégant. Brad Cox a introduit dans C les mécanismes de classes et d’envoi de messages de Smalltalk. Le résultat, Objective-C, est une extension très simple du langage C. En réalité, Objective-C était à l’origine un simple préprocesseur C et une bibliothèque.Objective-C n’est pas un langage propriétaire. Il s’agit d’un standard ouvert qui existe depuis des années dans le compilateur GNU C (gcc) de la FSF (Free Software Foundation). Plus récemment, Apple s’est fortement impliqué dans les projets de compilateurs open-source clang/LLVM (Low Level Virtual Machine), qui sont plus rapides et plus polyvalents que gcc. Dans les projets Xcode, LLVM est le compilateur par défaut.Cocoa a été développé à partir d’Objective-C, et la programmation Cocoa se fait généra-lement en Objective-C. Pour enseigner le langage C et les concepts de base de l’orienté objet, il faudrait un livre complet. Ce chapitre suppose que vous avez déjà quelques notions de C et de la programmation orientée objet et présente les bases d’Objective-C. Si vous correspondez à ce profil, vous constaterez que l’apprentissage d’Objective-C est facile. Dans le cas contraire, l’ouvrage The Objective-C Language d’Apple ou notre livre Programmation Objective-C, Le guide Big Nerd Ranch seront de bonnes introductions.

Créer et utiliser des instancesAu Chapitre 1, nous avons indiqué que les classes servaient à créer des objets, que les objets avaient des méthodes et qu’il était possible d’envoyer des messages aux objets pour déclencher l’invocation des méthodes. Dans cette section, vous allez apprendre à créer un objet et à lui envoyer des messages.

© 2013 Pearson France – Programmation Cocoa sous Mac OS X – Aaron Hillegass, Adam Preble

Page 2: Programmation Cocoa sous Mac OS X - 4e édition - Le guide ... · LLVM (Low Level Virtual Machine), qui sont plus rapides et plus polyvalents que gcc. Dans les projets Xcode, LLVM

34 Programmation Cocoa sous Mac OS X

Nous allons prendre en exemple la classe NSMutableArray. Pour créer une nouvelle instance de cette classe, il suffit de lui envoyer le message alloc :

[NSMutableArray alloc];

Cette méthode renvoie un pointeur sur l’espace qui a été alloué pour l’objet. Nous pouvons placer ce pointeur dans une variable :

NSMutableArray *toto;

toto = [NSMutableArray alloc];

Il est important de ne pas oublier que, dans le langage Objective-C, toto est uniquement un pointeur. Dans ce cas, il pointe sur un objet.Avant d’utiliser l’objet désigné par toto, nous devons nous assurer qu’il a été initialisé. La méthode init se charge de cette opération. Nous écrivons donc un code semblable au suivant :

NSMutableArray *toto;

toto = [NSMutableArray alloc];

[toto init];

Étudions la dernière ligne. Elle envoie le message init à l’objet sur lequel pointe la variable toto. Nous disons donc "toto est le destinataire du message init". Vous noterez que l’envoi d’un message implique un destinataire (l’objet désigné par toto) et un message (init), le tout placé entre des crochets. Il est également possible d’envoyer des messages à des classes, comme l’illustre l’envoi du message alloc à la classe NSMutableArray.La méthode init renvoie l’objet initialisé. C’est pourquoi les envois de ce message sont toujours écrits comme suit :

NSMutableArray *toto;

toto = [[NSMutableArray alloc] init];

Lorsqu’un objet est devenu inutile, nous pouvons le détruire. Le Chapitre 4 traite de ce sujet.Certaines méthodes prennent des arguments. Dans ce cas, le nom de la méthode, appelée sélecteur, se termine par des deux-points (:). Par exemple, pour ajouter des objets à la fin d’un tableau, nous utilisons la méthode addObject: (en supposant que tata est un pointeur sur un autre objet) :

[toto addObject:tata];

Si la méthode attend plusieurs arguments, le sélecteur est en plusieurs parties. Par exemple, pour ajouter un objet à un indice précis, nous écrivons le code suivant :

[toto insertObject:tata atIndex:5];

Notez que insertObject:atIndex: est un seul sélecteur, non deux. Il déclenche l’invocation d’une méthode avec deux arguments. Cela pourra sembler étrange aux programmeurs C et Java, mais très classique aux programmeurs Smalltalk. La syntaxe facilite également la lecture du code. Par exemple, il est assez fréquent de voir une méthode C++ semblable à la suivante :

if (x.intersectsArc(35.0, 19.0, 23.0, 90.0, 120.0))

© 2013 Pearson France – Programmation Cocoa sous Mac OS X – Aaron Hillegass, Adam Preble

Page 3: Programmation Cocoa sous Mac OS X - 4e édition - Le guide ... · LLVM (Low Level Virtual Machine), qui sont plus rapides et plus polyvalents que gcc. Dans les projets Xcode, LLVM

Chapitre 3 Objective-C 35

Il est beaucoup plus facile de comprendre la signification du code suivant :

if ([x intersectsArcWithRadius:35.0

centeredAtX:19.0

Y:23.0

fromAngle:90.0

toAngle:120.0])

Si ce code vous semble bizarre pour le moment, attendez un peu. La plupart des programmeurs finissent très rapidement par apprécier la syntaxe d’envoi de messages d’Objective-C.Vous êtes déjà arrivé au stade où vous pouvez lire du code Objective-C simple. Il est donc temps d’écrire un programme qui va créer une instance de NSMutableArray et la remplir avec dix instances de NSNumber.

Utiliser des classes existantesS’il n’est pas déjà ouvert, lancez Xcode. Fermez tous les projets sur lesquels vous étiez en train de travailler. Dans le menu FIle, choisissez new > project… Dans la fenêtre qui s’ouvre, sélectionnez command lIne tool (voir Figure 3.1).

Figure 3.1Choisir le type du projet.

© 2013 Pearson France – Programmation Cocoa sous Mac OS X – Aaron Hillegass, Adam Preble

Page 4: Programmation Cocoa sous Mac OS X - 4e édition - Le guide ... · LLVM (Low Level Virtual Machine), qui sont plus rapides et plus polyvalents que gcc. Dans les projets Xcode, LLVM

36 Programmation Cocoa sous Mac OS X

Un outil en ligne de commande ne possède pas d’interface graphique et s’utilise généralement depuis la ligne de commande ou en arrière-plan comme un démon. Contrairement à un projet d’application, nous modifions toujours la fonction main d’un outil en ligne de commande.Nommez le projet lottery (voir Figure 3.2). Contrairement aux noms des applications, les noms des outils sont généralement en minuscules. Fixez son type à FoundatIon.

Figure 3.2Nommer le projet.

Lorsque le nouveau projet apparaît, sélectionnez main.m dans le groupe lottery, puis modifiez ce fichier de la manière suivante :

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])

{

@autoreleasepool {

NSMutableArray *array;

array = [[NSMutableArray alloc] init];

int i;

for (i = 0; i < 10; i++) {

NSNumber *newNumber = [[NSNumber alloc] initWithInt:(i * 3)];

[array addObject:newNumber];

}

© 2013 Pearson France – Programmation Cocoa sous Mac OS X – Aaron Hillegass, Adam Preble

Page 5: Programmation Cocoa sous Mac OS X - 4e édition - Le guide ... · LLVM (Low Level Virtual Machine), qui sont plus rapides et plus polyvalents que gcc. Dans les projets Xcode, LLVM

Chapitre 3 Objective-C 37

for ( i = 0; i < 10; i++) { NSNumber *numberToPrint = [array objectAtIndex:i]; NSLog(@"Le nombre d’indice %d est %@", i, numberToPrint); } } return 0; }

Voici une explication détaillée de ce code :

#import <Foundation/Foundation.h>

Cette ligne inclut les en-têtes de toutes les classes qui se trouvent dans le framework Foundation. Puisque ces en-têtes sont déjà compilés, cette instruction n’est pas aussi lourde que vous pourriez le penser.

int main (int argc, const char *argv[])

La fonction main est déclarée comme elle le serait dans n’importe quel programme C Unix.

@autoreleasepool {

Cette ligne définit un pool à libération automatique pour le code placé entre les accolades. Nous reviendrons sur l’importance des pools à libération automatique (autorelease pool) au chapitre suivant.

NSMutableArray *array;

Cette ligne déclare une variable : array, qui est un pointeur sur une instance de NSMutableArray. Notez que le tableau n’existe pas encore. Le code déclare simplement un pointeur qui fera référence au tableau une fois qu’il aura été créé.

array = [[NSMutableArray alloc] init];

Voilà la création de l’instance de NSMutableArray et son affectation à la variable array qui pointe dessus.

for (i = 0; i < 10; i++) { NSNumber *newNumber = [[NSNumber alloc] initWithInt:(i*3)]; [array addObject:newNumber]; }

Dans la boucle for, une variable locale, nommée newNumber, est créée. Elle pointe sur une nouvelle instance de NSNumber. Ensuite, cet objet est ajouté au tableau.Le tableau n’effectue aucune copie des objets NSNumber. À la place, il conserve simplement une liste de pointeurs sur ces objets. Les programmeurs Objective-C font très peu de copies d’objets, car cette opération est rarement nécessaire.

for ( i = 0; i < 10; i++) { NSNumber *numberToPrint = [array objectAtIndex:i]; NSLog(@"Le nombre d’indice %d est %@", i, numberToPrint); }

© 2013 Pearson France – Programmation Cocoa sous Mac OS X – Aaron Hillegass, Adam Preble

Page 6: Programmation Cocoa sous Mac OS X - 4e édition - Le guide ... · LLVM (Low Level Virtual Machine), qui sont plus rapides et plus polyvalents que gcc. Dans les projets Xcode, LLVM

38 Programmation Cocoa sous Mac OS X

Ce code affiche le contenu du tableau sur la console. NSLog est une fonction semblable à la fonction printf() de C. Elle prend une chaîne de format et une liste de variables séparées par des virgules, dont les valeurs remplaceront les paramètres dans la chaîne de format. Lors de l’affichage, NSLog ajoute avant la chaîne le nom de l’application et une estampille temporelle.Avec printf, par exemple, il faut utiliser %x pour afficher un entier sous forme hexadécimale. Avec NSLog, nous disposons de toutes les options de printf, avec en plus %@ pour afficher un objet. L’objet reçoit le message description et la chaîne renvoyée remplace le paramètre %@. Nous reviendrons sur la méthode description un peu plus loin.Le Tableau 3.1 recense toutes les options reconnues par NSLog().

Tableau 3.1 : Options reconnues dans les chaînes de format d’Objective-C

Symbole Affichage

%@ identifiant

%d, %D, %i long

%u, %U long non signé

%hi court

%hu court non signé

%qi long long

%qu long long non signé

%x, %X long non signé sous forme hexadécimale

%o, %O long non signé sous forme octale

%f, %e, %E, %g, %G double

%c char non signé sous forme de caractère ASCII

%C unichar sous forme de caractère Unicode

%s char * (une chaîne C de caractères ASCII terminée par null)

%S unichar * (une chaîne C de caractères Unicode terminée par null)

%p void * (une adresse affichée sous forme hexadécimale en commençant par 0x)

%% caractère %

Si vous trouvez que le signe @ qui précède les guillemets dans @"Le nombre d’indice %d est %@" est un peu étrange, n’oubliez pas qu’Objective-C n’est que le langage C avec quelques extensions. En particulier, les chaînes sont des instances de la classe NSString. En C, les chaînes de caractères sont simplement des pointeurs sur un tampon de caractères qui se termine par le caractère null. Les chaînes C et les instances de NSString peuvent être utilisées dans le même fichier. Pour différencier les chaînes C constantes et les NSString constants, nous devons placer le signe @ avant les guillemets ouvrants d’une constante NSString :

Info

© 2013 Pearson France – Programmation Cocoa sous Mac OS X – Aaron Hillegass, Adam Preble

Page 7: Programmation Cocoa sous Mac OS X - 4e édition - Le guide ... · LLVM (Low Level Virtual Machine), qui sont plus rapides et plus polyvalents que gcc. Dans les projets Xcode, LLVM

60 Programmation Cocoa sous Mac OS X

Figure 3.16L’analyseur statique à l’œuvre.

Pour les plus curieux : mécanisme des messagesNous l’avons mentionné précédemment, un objet peut être comparé à une structure C. NSObject déclare une variable d’instance nommée isa. Puisque NSObject est la racine de l’arborescence d’héritage des classes, chaque objet possède sa variable isa, qui est un pointeur sur la structure de classe qui a créé l’objet (voir Figure 3.17). La structure de classe comprend les noms et les types des variables d’instance de la classe, ainsi que l’implémentation des méthodes de la classe. Et également un pointeur vers la structure de classe de sa classe mère.

Figure 3.17Chaque objet possède un pointeur sur sa classe.

© 2013 Pearson France – Programmation Cocoa sous Mac OS X – Aaron Hillegass, Adam Preble

Page 8: Programmation Cocoa sous Mac OS X - 4e édition - Le guide ... · LLVM (Low Level Virtual Machine), qui sont plus rapides et plus polyvalents que gcc. Dans les projets Xcode, LLVM

Chapitre 3 Objective-C 61

Les méthodes sont indexées par le sélecteur, qui est du type SEL. Bien que SEL soit défini comme char *, il est plus facile de le considérer comme un entier (int). Chaque nom de méthode est associé à un entier unique. Par exemple, le nom de méthode addObject: pourrait être associé au nombre 12. Lorsque nous recherchons des méthodes, nous utilisons le sélecteur, non la chaîne @"addObject:".Dans les structures de données Objective-C, un tableau associe les noms des méthodes à leur sélecteur. La Figure 3.18 montre un exemple.

Figure 3.18Le tableau des sélecteurs.

À la compilation, le compilateur examine les sélecteurs dès qu’il rencontre un envoi de messages. Alors, l’instruction

[monObjet addObject:votreObjet];

devient (en supposant que le sélecteur de addObject: soit 12)

objc_msgSend(monObjet, 12, votreObjet);

objc_msgSend() examine le pointeur isa de monObjet pour obtenir sa structure de classe et recherche la méthode associée au nombre 12. Si elle n’en trouve aucune, elle suit le pointeur vers la classe mère. Si celle-ci n’a pas de méthode correspondant à 12, la recherche continue vers le sommet de l’arborescence. Lorsque la racine est atteinte, sans que la méthode soit trouvée, la fonction lance une exception.Cette gestion des messages est clairement une solution très dynamique. Les structures de classe peuvent être modifiées à l’exécution. En particulier, avec la classe NSBundle, il est relativement facile d’ajouter des classes et des méthodes à un programme pendant son exécution. Cette technique très puissante est utilisée pour créer des applications qui peuvent être étendues par d’autres développeurs.

DéfiUtilisez la méthode setDateFormat: de NSDateFormatter pour personnaliser la chaîne de format des objets de date dans la classe LotteryEntry.

© 2013 Pearson France – Programmation Cocoa sous Mac OS X – Aaron Hillegass, Adam Preble