• 20 heures
  • {0} Facile|{1} Moyenne|{2} Difficile

Ce cours est visible gratuitement en ligne.

Ce cours existe en livre papier.

J'ai tout compris !

Mis à jour le 21/06/2013

La programmation orientée objet

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Dans ce chapitre, vous allez dans un premier temps découvrir ce qui se cache derrière la programmation orientée objet (POO). Vous verrez ensuite comment mettre en œuvre ce type de programmation en utilisant le langage Objective-C.

La programmation orientée objet est une notion difficile à comprendre, aussi n'hésitez pas à lire ce chapitre plusieurs fois, à tête reposée. Vous verrez, cela devrait finir par rentrer !

Qu'est-ce que la programmation Orientée Objet ?

Dans la programmation « traditionnelle », les programmes sont constitués d'un ensemble d'instructions qui s'exécutent les unes à la suite des autres (voir figure suivante).

Les instructions s'exécutent les unes à la suite des autres

Dans la plupart des programmes, on définit une boucle qui ne fait rien d'autre qu'attendre l'arrivée d'un événement. Par exemple, la fin d'un calcul, un changement d'heure, un clic souris ou un autre type d'événement quelconque. Si aucun événement ne se produit, la boucle se contente d'attendre, encore et encore. C'est pourquoi on l'appelle souvent « boucle d'attente ». Si un événement survient, il est identifié et traité en conséquence. La figure suivante illustre mes propos.

Dans la plupart des programmes, on attend un événement

Dans la programmation orientée objet, les programmes sont constitués d'un ensemble de blocs de code indépendants appelés objets. Chaque objet contient sa propre boucle d'attente. Lorsqu'un événement concernant un objet particulier survient, c'est à cet objet de traiter l'événement, comme le montre la figure suivante.

Avec la POO, ce sont les objets qui traitent les événements

Les langages orientés objet utilisent plusieurs termes techniques bien particuliers. Pour vous aider à les appréhender, je vais utiliser une analogie en me basant sur des objets courants de la vie de tous les jours : des voitures.

Une voiture est définie par un ensemble de caractéristiques : modèle et couleur entre autres. Elle est fabriquée dans une usine. Lors de la fabrication, une ou plusieurs options sont ajoutées au modèle de base.

Dans un langage orienté objet :

  • l'usine est une classe : c'est elle qui fabrique les objets ;

  • la voiture est un objet ;

  • les caractéristiques de la voiture sont des propriétés ;

  • les options sont des méthodes de la classe Usine.

Je vous ai fait un schéma en figure suivante pour vous aider à mieux visualiser tout ça.

Une voiture est un objet

Maintenant que vous avez le vocabulaire nécessaire, nous allons rentrer dans le vif du sujet.

Définir une classe

Revenons au petit monde des devices Apple. Une application iOS est bâtie autour d'une classe qui contient un ensemble d'objets, de propriétés (qui représentent l'état des objets) et de méthodes (qui régissent le fonctionnement des objets) (voir figure suivante) .

Une application iOS est bâtie autour d'une classe qui contient un ensemble d'objets, de propriétés et de méthodes

Supposons que vous vouliez définir la classe maClasse (oui, je sais, c'est très original !).
Vous devrez agir dans deux fichiers distincts : maClasse.h et maClasse.m.

  • maClasse.h est un fichier d'en-têtes. Il est utilisé pour déclarer les éléments manipulés dans le code.

  • maClasse.m contient le code source de l'application.

Le fichier .h

Pour interagir avec ses utilisateurs, une application utilise une interface. Dans une application iOS, cette interface peut contenir du texte, des images, des vidéos, des boutons et bien d'autres choses encore. En tant que programmeur, vous devrez utiliser des classes pour définir ces différents éléments. Bien qu'il soit possible de définir à partir de zéro tous ces éléments (forme, ombrage, couleur, comportement sur l'écran etc.), vous préférerez sans aucun doute utiliser des classes toutes faites. Pour faciliter la vie des développeurs, Apple a eu la bonne idée de regrouper ces classes dans une sorte de boîte à outils (on dit aussi framework) appelée UIKit. C'est par son intermédiaire que vous pourrez ajouter du texte, des images, des boutons, des vidéos, etc. à vos applications.

Pour établir le lien entre l'application en cours de développement et le framework UIKit, la première instruction d'un fichier .h doit toujours être la suivante :

#import <UIKit/UIKit.h>

Cette simple instruction donne accès à toutes les classes du framework UIKit.

Les lignes qui suivent l'instruction #import définissent le nom et le type de l'application, ainsi que les variables utilisées dans l'application :

@interface nom : type
{
Une ou plusieurs variables
}

nom est le nom de l'application et type définit son type.

Supposons donc que vous définissiez l'application test de type UIViewController. L'instruction @interface aura l'allure suivante :

@interface testViewController : UIViewController
{
//Une ou plusieurs variables
}

Les variables définies entre les accolades sont appelées variables d'instance.

Qu'est-ce encore que cela ?

Quand vous développez une application iOS, vous définissez une nouvelle classe. Lorsque l'application est lancée, on dit qu'une « instance de la classe » est créée. Cela signifie qu'un objet de cette classe est créé. Les variables d'instance sont propres à cette instance : si vous lancez deux fois l'application, les variables utilisées dans la première instance ne seront pas liées à la seconde, et inversement. Si vous avez du mal à comprendre, la figure suivante devrait vous éclairer.

Chaque instance de classe  a des variables qui lui sont propres

Voici un exemple de fichier d'en-têtes .h :

#import <UIKit/UIKit.h>
@interface Voiture : NSObject {
NSString* modele;
NSString* couleur;
}
@end

La classe a pour nom Voiture. Le fichier qui définit l'interface a donc pour nom Voiture.h.

La classe Voiture possède deux variables d'instance NSString : modele et couleur.

Pas si vite ! Qu'est-ce que signifie NSString et pourquoi y a-t-il un astérisque après ce mot ?

NSString représente le type des variables modele et couleur. Il s'agit d'un type permettant de manipuler des chaînes de caractères.
L'astérisque indique que les variables modele et couleur sont des pointeurs de NSString. Elles contiendront donc l'adresse des chaînes et non les chaînes elles-mêmes. Comme vous le verrez tout au long de ce livre, l'utilisation de pointeurs dans Objective-C est monnaie courante.

Définir des variables d'instance, c'est bien, mais pouvoir y accéder, c'est mieux ! En effet, les variables d'instance sont là pour mémoriser des données, et ces données doivent pouvoir être écrites dans les variables d'instance et lues depuis les variables d'instance.

Pour accéder aux variables d'instance, nous allons ajouter des getters (pour connaître la valeur stockée dans les variables) et des setters (pour stocker des valeurs dans les variables et y accéder) :

- (NSString*) modele;
- (NSString*) couleur;
- (void) setModele: (NSString*)input;
- (void) setCouleur: (NSString*)input;

Les deux premières instructions sont des getters. Elles permettent de lire les valeurs stockées dans les variables d'instance modele et couleur ; en d'autres termes, de connaître le modèle et la couleur de la voiture. La valeur renvoyée est de type NSString. Au début de ces deux lignes, le signe - indique qu'il s'agit de méthodes d'instance.

Les deux dernières lignes sont des setters. Elles permettent de stocker des valeurs dans les variables d'instance modele et couleur, c'est-à-dire définir le modèle et la couleur de la voiture. Ici aussi, il s'agit de méthodes d'instance, d'où le signe - au début des instructions. Ces méthodes ne renvoient aucune valeur, ce qui explique le (void) au début des instructions.

Le fichier d'en-têtes est maintenant complet. Voici les instructions qui le composent :

#import <UIKit/UIKit.h>
@interface Voiture : NSObject {
NSString* modele;
NSString* couleur;
}
- (NSString*) modele;
- (NSString*) couleur;
- (void) setModele: (NSString*)input;
- (void) setCouleur: (NSString*)input;
@end

Le fichier .m

Nous allons maintenant implémenter (c'est-à-dire écrire le code de) la classe Voiture en définissant ses getters et ses setters dans le fichier Voiture.m. Je vous rappelle que les getters vont permettre de lire le contenu des variables d'instance et que les setters vont permettre de les modifier.

Commençons par les getters. Le but du jeu est d'obtenir la valeur stockée dans les variables d'instance modele et couleur. Une simple instruction return fera donc l'affaire :

#import "Voiture.h"
@implementation Voiture
- (NSString*) modele {
return modele;
}
- (NSString*) couleur {
return couleur;
}
@end

Passons maintenant aux setters. Leur but est de modifier les valeurs contenues dans les variables d'instance modele et couleur. Que pensez-vous du code suivant ?

- (void) setModele: (NSString*)nouvModele {
modele = nouvModele;
}
- (void) setCouleur: (NSString*)nouvCouleur {
couleur = nouvCouleur;
}

Vous devez encore écrire une méthode pour définir et initialiser les variables d'instance. Cette méthode est le constructeur de la classe. Elle pourrait contenir quelque chose comme ceci :

- (id) init
{
if ( self = [super init] )
{
[self setModele:@"Maserati Spyder"];
[self setCouleur:@"Rouge"];
}
return self;
}

La première ligne identifie le constructeur. Ne cherchez pas à comprendre le pourquoi du comment : c'est la syntaxe à utiliser !

En observant les lignes 5 et 6, vous pouvez déduire que ces deux instructions affectent la valeur « Maserati Spyder » à la variable d'instance modele en utilisant le setter setModele et la valeur « Rouge » à la variable d'instance couleur en utilisant le setter setCouleur. Rien ne vous empêche de choisir d'autres valeurs par défaut, mais j'ai pensé que ce choix n'était pas dépourvu d'intérêt.

La troisième ligne affecte le résultat de [super init] à self.

Mais qu'est-ce que c'est que tout ce charabia ? Des explications s'il vous plaît !

Le mot self identifie l'objet courant. Dans notre cas, une instance de la classe Voiture. Quant au mot super, il identifie la classe « parente », c'est-à-dire la classe à partir de laquelle la classe Voiture a été créée. Un simple coup d'œil au fichier Voiture.h nous montre que la classe parente de Voiture est NSObject :

@interface Voiture : NSObject {
...
}

[super init] exécute donc la méthode init de la classe parente. Ici, NSObject. Cette méthode initialise la classe Voiture. La valeur renvoyée est nil si un problème s'est produit pendant l'initialisation. Dans le cas contraire, l'adresse de l'objet Voiture est renvoyée.

L'instruction if teste la valeur stockée dans self, c'est-à-dire la valeur retournée par [self init]. Si la valeur renvoyée est différente de nil, les variables d'instance peuvent être initialisées. Dans le cas contraire, il est inutile de poursuivre l'exécution puisque l'initialisation de la classe a échoué.

J'espère que l'initialisation de la classe n'a maintenant plus aucun secret pour vous. N'hésitez pas à relire plusieurs fois les lignes qui précèdent jusqu'à ce que vous ayez bien compris. Ne vous en faites toutefois pas si vous ne comprenez pas encore parfaitement cette section. Cela viendra avec la pratique et vous n'en êtes encore qu'à vos premiers pas en programmation Objective-C. Et croyez-moi, c'est assurément la partie la plus difficile de votre apprentissage !

Allez, pour vous encourager, voici le code complet du fichier Voiture.m :

#import "Voiture.h"
@implementation Voiture
- (NSString*) modele {
return modele;
}
- (NSString*) couleur {
return couleur;
}
- (void) setModele: (NSString*)nouvModele
{
modele = nouvModele;
}
- (void) setCouleur: (NSString*)nouvCouleur
{
couleur = nouvCouleur;
}
- (id) init
{
if ( self = [super init] )
{
[self setModele:@"Ferrari 360"];
[self setCouleur:@"Rouge"];
}
return self;
}
@end

Définir des méthodes

Les méthodes Objective-C peuvent être attachées à une classe (méthode de classe) ou à une instance (méthode d'instance). Par exemple, stringWithFormat est une méthode de classe, rattachée à la classe NSString ; ou encore arrayWithArray est une méthode de classe, rattachée à la classe NSArray.

Dans une de vos applications, vous pourriez être amenés à définir une méthode d'instance nombreElementsTableau qui renverrait le nombre d'éléments du tableau qui lui est communiqué en paramètre.
Voici la syntaxe générale permettant de déclarer une méthode :

typeMethode (typeRetour) nomMethode : paramètres
{
//Une ou plusieurs instructions
};

Où :

  • typeMethode vaut + pour une méthode de classe ou - pour une méthode d'instance ;

  • typeRetour est le type de l'objet retourné par la méthode ;

  • nomMethode est le nom de la méthode ;

  • parametres correspond aux paramètres de la méthode, s'ils existent. Dans ce cas, ils sont constitués d'un ou de plusieurs couples (type)nom, où type est le type du paramètre et nom le nom du paramètre.

Quelques exemples vont vous aider à y voir plus clair.
L'instruction suivante déclare la méthode d'instance premierJour, qui renvoie le nom du premier jour de la semaine lorsqu'on lui transmet une année (an) et un numéro de semaine (numSem) :

- (NSString *) premierJour : (int) an: (int) numSem;

Cette autre instruction déclare la méthode de classe maMethode, qui ne renvoie rien (void) et qui ne demande aucun paramètre :

+ (void) maMethode ;

Enfin, cette dernière instruction déclare la méthode d'instance changePropriete, qui renvoie un booléen et qui admet deux paramètres : le nom de la propriété à modifier (prop) et la valeur à lui affecter (valeur) :

- (BOOL) changePropriete: (NSString *)prop: (NSString *)valeur;

Appeler des méthodes

Avant la pratique, un peu de théorie

En Objective-C, appeler une méthode de classe revient à envoyer un message. Pour cela, on utilise une syntaxe un peu particulière : le nom de l'objet est placé entre crochets et on le fait suivre du nom de la méthode :

[objet methode];

Si la méthode demande une valeur en entrée, faites suivre le nom de la méthode par le caractère « : » et entrez la valeur après ce caractère :

[objet methode:entree];

Si une méthode demande plusieurs paramètres, séparez-les par un espace et indiquez la valeur de ces paramètres après le caractère « : ». Ici par exemple, trois paramètres sont transmis à la méthode. Le premier suit le nom de la méthode (methode:valeur1) et les deux autres sont précédés du nom du paramètre correspondant (param2:valeur2 et param3:valeur3) :

[objet methode:valeur1 param2:valeur2 param3:valeur3];

Une méthode peut retourner un objet. Dans ce cas, vous pouvez le stocker dans une variable :

variable = [objet methode];

Ou encore :

variable = [objet methode:entree];

Si la méthode retourne un objet, vous pouvez enchaîner plusieurs appels de méthodes (c'est d'ailleurs ce qu'on appelle un chaînage). Dans l'exemple suivant, le paramètre param1 est envoyé à la méthode methode1, et cette dernière est appliquée à l'objet objet1. Le résultat de la méthode est un objet auquel on applique la méthode methode2 avec le paramètre param2 :

[[objet1 methode1:param1] methode2:param2];

Si les choses ne sont pas très claires, examinez la figure suivante.

Le paramètre param1 est envoyé à la méthode methode1, et cette dernière est appliquée à l'objet objet1

Je ne comprends rien à ce schéma ! Pourrais-je avoir quelques explications ?

Pour comprendre ce schéma, il suffit de suivre les flèches, de la gauche vers la droite.

parametre 1 est passé à la methode 1 de l'objet 1. Cette méthode fait un traitement et retourne un résultat sous la forme d'un objet (la deuxième flèche rouge). La methode 2 de cet objet est exécutée, en lui passant le parametre 2 en entrée (la troisième flèche rouge). Le résultat final est représenté par la quatrième flèche rouge.
J'espère que c'est plus clair cette fois-ci. Dans le cas contraire, relisez ce qui vient d'être dit. Il n'y a rien de vraiment sorcier là-dedans… ;-)

Les méthodes ne sont pas l'apanage des objets : elles peuvent également être appliquées à des classes. Par exemple, pour créer une variable de type NSString, vous appliquerez la méthode string de la classe NSString :

NSString* uneChaine [NSString string];

Cette instruction peut être simplifiée comme suit :

NSString* uneChaine;

Je suis sûr que vous préférez la deuxième syntaxe à la première. Je dois bien avouer que moi aussi !

Appel d'une méthode existante

Et maintenant, un peu de pratique. Vous allez utiliser un peu de code Objective-C pour concaténer (coller si vous préférez) deux chaînes NSString et afficher le résultat dans la console du Simulateur iOS.

Définissez un nouveau projet basé sur le modèle Single View Application et donnez-lui le nom « test ».
Cliquez sur ViewController.m dans le volet de navigation et repérez la méthode viewDidLoad. Cette méthode est exécutée dès le démarrage de l'application. Vous allez y ajouter quelques instructions pour tester l'exécution de méthodes.
La méthode viewDidLoad (ainsi que de nombreuses autres méthodes) a été générée par Xcode. Voici à quoi elle doit ressembler :

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}

Le message [super viewDidLoad] exécute la méthode viewDidLoad de la classe parente (super) de la classe en cours d'exécution. Étant donné que notre classe test hérite de la classe UIView, cette instruction va exécuter la méthode viewDidLoad de la classe UIView.

La ligne de commentaire n'a aucune utilité. Vous pouvez la supprimer.
Pour concaténer deux chaînes, vous utiliserez la méthode stringByAppendingString en envoyant un message du type suivant :
[chaine1 stringByAppendingString: chaine2];
chaine1 et chaine2 sont les deux chaînes à concaténer.

Complétez la méthode viewDidLoad comme suit :

- (void)viewDidLoad
{
[super viewDidLoad];
NSString* chaine = @"un ";
chaine = [chaine stringByAppendingString:@"texte"];
NSLog(@"%@",chaine);
}

Exécutez l'application en cliquant sur l'icône Run. La figure suivante représente ce que vous devriez obtenir dans la console.

Nos deux chaînes ont bien été concaténées

Examinons les instructions utilisées dans la méthode viewDidLoad.

La ligne 4 définit l'objet NSStringchaine et lui affecte la valeur « un » :

NSString* chaine = @"un ";

La ligne 5 applique la méthode stringByAppendingString à l'objet NSStringchaine en lui passant le paramètre « texte ». Le résultat est stocké dans l'objet chaine (chaine =) :

chaine = [chaine stringByAppendingString:@"texte"];

Enfin, la ligne 6 affiche le contenu de l'objet chaine (c'est-à-dire « un texte ») :

NSLog(@"%@",chaine);

Création et appel d'une méthode

Vous venez d'apprendre à appeler la méthode stringByAppendingString. Cette méthode fait partie des méthodes standards de la classe NSString.
Vous allez maintenant aller un peu plus loin en créant une méthode et en l'appelant. Cette méthode :

  1. aura pour nom « concat » ;

  2. recevra deux paramètres NSString ;

  3. renverra leur concaténation dans un objet NSString.

Munis de toutes ces informations, vous devriez pouvoir définir le gabarit (c'est-à-dire l'allure) de la méthode :

-(NSString*) concat:(NSString*)ch1: (NSString*)ch2;

Cliquez sur ViewController.h dans le volet de navigation et ajoutez ce gabarit dans le fichier d'en-têtes, après l'instruction @interface.

Il n'y a rien de bien compliqué dans ce gabarit. Si vous ne comprenez pas comment il est construit, relisez la section « Définir des méthodes ».
Le fichier d'en-têtes doit maintenant ressembler à ceci :

#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
-(NSString*) concat:(NSString*)ch1: (NSString*)ch2;
@end

Maintenant, vous allez écrire quelques lignes de code dans le fichier ViewController.m. Cliquez sur ce fichier dans le volet de navigation et définissez la méthode concat, juste au-dessous de l'instruction @implementation :

-(NSString*) concat:(NSString*)ch1: (NSString*)ch2
{
return [ch1 stringByAppendingString:ch2];
}

La première ligne reprend le gabarit de la fonction.

La troisième ligne définit l'objet retourné par la méthode (viareturn). Cet objet est le résultat de la concaténation de ch1 et ch2, passés en arguments.

Et maintenant, modifiez la méthode viewDidLoad comme suit pour appeler la méthode concat et afficher le résultat retourné dans la console :

- (void)viewDidLoad
{
[super viewDidLoad];
NSString* chaine = [self concat: @"premier ":@"deuxième"];
NSLog(@"%@",chaine);
}

La ligne 4 définit le NSString chaine (NSString* chaine) et lui affecte la valeur retournée par la méthode concat, en lui passant les NSString « premier » et « deuxième ».

Que signifie le mot self dans ce code ?

Il signifie que la méthode concat a été définie dans la classe courante, tout simplement.

Enfin, la ligne 5 affiche le résultat retourné par concat dans la console. Exécutez l'application. La figure suivante représente ce que vous devriez obtenir dans la console.

Les deux chaînes ont bien été concaténées

Crochet ou point ?

Deux styles d'écriture peuvent être utilisés pour appeler une méthode : les crochets ou les points. À titre d'exemple, les deux instructions suivantes sont équivalentes :

[voiture setCouleur:@"rouge"];
voiture.couleur = @"rouge";

Ces deux écritures font une seule et même action : elles appliquent la méthode couleur à l'objet voiture en lui passant l'entrée rouge.

Les deux lignes suivantes sont elles aussi équivalentes :

laCouleur = [voiture couleur];
laCouleur = voiture.couleur;

Vous l'aurez compris, elles lisent la couleur de l'objet voiture et la stockent dans la variable laCouleur.

Créer un objet

La gestion mémoire d'un objet peut être automatique ou manuelle. Dans le premier cas, lorsque l'objet n'est plus utilisé, il est automatiquement retiré de la mémoire. Dans le deuxième cas, c'est à vous de le retirer de la mémoire pour éviter qu'elle ne se sature.
À titre d'exemple, pour créer l'objet NSString maChaine avec une gestion automatique de la mémoire, vous utiliserez l'instruction suivante :

NSString* maChaine = [NSString string];

Ou plus simplement :

NSString* maChaine;

Si vous préférez gérer manuellement l'objet NSString maChaine en mémoire, vous utiliserez l'instruction suivante :

NSString* maChaine = [[NSString alloc] init];

Examinons cette deuxième écriture. Dans un premier temps, la méthode alloc est appliquée à la classe NSString. Cette opération réserve un espace mémoire et instancie un objet NSString. Dans un deuxième temps, la méthode init est appliquée à cet objet pour l'initialiser et le rendre utilisable (ce n'est qu'après l'initialisation de l'objet que l'on peut lui appliquer des méthodes).

Si nécessaire, il est possible d'affecter une valeur à un objet NSString.

Voici l'instruction à utiliser si vous optez pour une gestion automatique de la mémoire :

NSString* maChaine = [NSString stringWithString:@"Une chaîne quelconque"];

Ou plus simplement :

NSString* maChaine = @"Une chaîne quelconque";

Et voici les instructions à utiliser si vous optez pour une gestion manuelle de la mémoire :

NSString* maChaine2 = [[NSString alloc] init];
maChaine2 = @"Une chaîne quelconque";

Cycle de vie des objets

Tout comme les êtres vivants, les objets utilisés dans une application iOS ont un cycle de vie.

  1. Création.

  2. Utilisation.

  3. Destruction.

Une très bonne nouvelle : iOS 5 introduit un système nommé ARC (Automatic Reference Counting) qui automatise le cycle de vie des objets. Désormais, c'est le compilateur qui se charge de cette tâche ingrate qui consiste à détruire les objets une fois qu'ils ne sont plus utilisés.

Je ne m'étendrai pas plus sur le sujet, mais sachez que vous échappez à des complications aussi inutiles que dangereuses.

En résumé

  • En programmation orientée objet, les programmes sont constitués d'un ensemble de blocs de code indépendants appelés objets. Chaque objet contient sa propre boucle d'attente. Lorsqu'un événement concernant un objet particulier survient, c'est à cet objet de traiter l'événement.

  • Via l'instruction #import <UIKit/UIKit.h>, le fichier .h fait référence au framework UIKit. Il définit également l'interface de l'application, les variables d'instance, et leurs accesseurs (getters et setters).

  • Le fichier .m implémente les getters et les setters des objets utilisés dans l'application, ainsi qu'une ou plusieurs méthodes complémentaires pour effectuer les traitements demandés par l'application.

  • Les variables d'instance sont propres à une instance de classe. Si plusieurs instances sont exécutées, les variables n'entreront donc pas en conflit.

  • Les méthodes sont appelées par l'intermédiaire de messages de type [objet methode]; ou [objet methode:entree];. Les méthodes peuvent être chaînées en imbriquant plusieurs messages : [[objet1 methode1: param1] methode2: param2];.

  • Pour appeler une méthode d'une variable d'instance, il est possible d'utiliser une syntaxe « à point ». Ainsi, [objet methode] et objet.methode sont équivalents.

  • Dans iOS 5, le système ARC (Automatic Reference Counting) automatise le cycle de vie des objets : désormais, c'est le compilateur qui se charge de détruire les objets une fois qu'ils ne sont plus utilisés.

Exemple de certificat de réussite
Exemple de certificat de réussite