Magazine High tech

La gestion de la mémoire (2)

Publié le 27 novembre 2009 par Jibaku @fabien_schwob

Dans le premier épisode, nous avons vu qu'un objet qui avait alloué la mémoire pour un autre objet était également responsable de la libérer lorsque l'objet ne lui était plus nécessaire. Ce système est similaire à l'allocation dynamique de la mémoire telle qu'on la connaît en langage C sous la formes des fonctions malloc() et free().

Cependant, ce système comporte un inconvénient majeur dès qu'un objet est passé d'un objet à un autre. Étudions la séquence suivante:

  • Un objet A alloue un objet B.
  • L'objet A passe l'objet B à un objet C. L'objet C garde un pointeur sur l'objet B dont il a encore besoin par la suite.
  • L'objet A n'a plus besoin de l'objet B. Il lui envoie donc un message -[release].
  • L'objet C tente d'appeler une méthode de l'objet B, ce qui mène à un plantage.

Il a donc fallu incorporer un système qui permette de conserver un objet en mémoire tant qu'il est nécessaire, et le libérer lorsqu'il ne l'est plus. Ce système est l'autorelease.

Autorelease pool

Examinons l'exemple suivant:

NSArray* monArray = [[NSArray alloc] init];
[monArray autorelease];

La première ligne alloue, comme nous l'avons vu la dernière fois, un objet de type NSArray et l'initialise. La deuxième ligne ajoute monArray à l'autorelease pool courant.

Un objet de type NSAutoreleasePool conserve une liste d'objets. Ces objets seront désalloués à la fin de la boucle d'événements.

La boucle d'événements

Le moteur d'exécution (runtime) est un programme qui offre une structure à l'exécution des programmes écrits en Objective-C. Il comporte une boucle d'événements:

  • Au début de la boucle, les événements (frappe clavier, mouvements de la souris, timers écoulés, messages des autres applications, etc.) sont récupérés.
  • L'application (votre code !) traite les événements.
  • Les autorelease pools sont vidés
  • Puis on revient au début de la boucle.

Ce principe permet de garantir l'existence de l'objet pendant l'exécution d'un itération de votre code.

Dans les applications Cocoa utilisant une interface graphique, un NSAutoreleasePool est instancié automatiquement pour le thread principal. En général, vous n'avez donc pas besoin d'en créer un. Vous serez toutefois amené à le faire si vous concevez une application multi-thread, ou si vous instanciez un grand nombre d'objets dont la durée de vie est limitée.

Retain/Release

La gestion de la mémoire en Objective-C est souvent expliquée par l'analogie suivante: un petit chien se met à courir dès qu'il n'a plus aucune laisse autour du cou. Tant qu'il a au moins une laisse au cou, il ne peut s'échapper. Évidemment, s'il a plusieurs laisses qui le retiennent, il ne peut pas non plus s'enfuir.

Envoyer un message -[retain] à un objet lui passe une laisse autour du cou.

Lui envoyer un message -[release] lui retire une laisse.

Concrètement, chaque objet héritant de NSObject possède une variable d'instance retainCount. Il s'agit du nombre de "laisses":

  • +[alloc] initialise retainCount à 1.
  • -[autorelease] décrémente retainCount et place l'objet dans l'autorelease pool courant.
  • -[release] décrémente retainCount
  • -[retain] incrémente retainCount

Lorsque survient la fin de la boucle d'événements, l'autorelease pool libère tous les objets dont le retainCount est nul.

Constructeurs de commodité

Il arrive fréquemment de créer un objet, de le passer à un autre objet, puis de ne plus en avoir besoin. Les deux exemples suivants sont équivalents. Nous voulons passer une liste d'invités à un objet fiesta:

Exemple 1:

NSArray* invites = [[NSArray alloc] initWithObjects:@"Pascal", @"Florence", @"Martin", @"Patrick"];
[invites autorelease];
[fiesta setInvites:invites];

Exemple 2:

NSArray* invites = [NSArray arrayWithObjects:@"Pascal", @"Florence", @"Martin", @"Patrick"];
[fiesta setInvites:invites];

La méthode +[arrayWithObjects:] est un constructeur de commodité, qui permet de faire l'allocation, l'initialisation et l'autorelease en une seule opération. Ce type de méthodes est très courant dans Cocoa. En fait par convention, si le premier mot du nom d'une méthode est celui de la classe, vous est certain que l'objet renvoyé est autoreleasé.

Ajout à une collection

Pour finir, sachez que les collections retiennent les objets qu'elle contiennent. C'est à dire que les objets de types: NSArray, NSSet, NSDictionary et compagnie, envoient un message -[retain] aux objets qui leurs sont ajoutés. Quand la collection est libérée, elle envoie un message -[release] à tous les objets qu'elle contient.

Exemple:

@interface Livre : NSObject
{
    NSMutableArray* pages;  
}

@end

@implementation Livre
- (id) init
{
    if(self = [super init])
    {
        // Créer la liste des pages
        pages = [[NSMutableArray* alloc] init];

        // Ajouter une première page vierge
        Page* pageVierge = [[Page alloc] init];     // retainCount = 1
        [pages addObject:pageVierge];               // retainCount = 2
        [pageVierge release];                       // retainCount = 1
    }
    return self;    
}

- (void) dealloc
{
    [pages release];

    [super dealloc];    
}

L'objet pageVierge reçoit un message -[retain] quand elle est ajoutée au NSMutableArray pages. Nous devons donc lui envoyer un message -[release] pour qu'elle soit effectivement désallouée lorsque le livre sera désalloué.

Bientôt la suite

Nous n'en n'avons pas encore fini. Je vous encourage à poser des questions si un aspect n'est pas clair et que vous souhaitez le voir développé.

Renaud Pradenc
Céroce


Vous pourriez être intéressé par :

Retour à La Une de Logo Paperblog

Ces articles peuvent vous intéresser :

  • Joyeux anniversaire B. !

    Joyeux anniversaire

    B., du fond de sa Guyane, goûte les confitures de Natalia... Voici l"assortiment d'été" qu'elle pourra glisser dans ses valises lors de son prochain passage en... Lire la suite

    Par  Natalia Kriskova
    CUISINE, RECETTES
  • B comme « bande-son »

    comme bande-son

    Ipod, lecteur de CD dans la bagnole, peut importe le support pourvu d’avoir l’ivresse musicale. Avant de penser faire sa valise, réfléchir à la quinzaine de... Lire la suite

    Par  Jeanyvessecheresse
    A CLASSER
  • B comme « bouquins »

    comme bouquins

    Hier je bourrais la valise de quelques disques destinés à parcourir l’été. Aujourd’hui les tâches logistiques se poursuivent puisqu’il s’agit de sélectionner... Lire la suite

    Par  Jeanyvessecheresse
    A CLASSER
  • in B flat

    flat

    Une petite piece musicale 2.0 initiée par Daren Solomon (science for Girls). Le principe etait simple, chaque utilisateur devait jouer un theme musical sur la... Lire la suite

    Par  Newwavehooker
    CULTURE, MUSIQUE, POP/ROCK
  • Le B-17

    Lire la suite

    Par  Theatrum Belli
    A CLASSER
  • Agnès b.(iba)...

    Agnès b.(iba)...

    Comme je vous en parlais le mois dernier, après le maillot de bain DnuD, l'édition de septembre du magazine Biba propose, pour 4,40 euros, une robe Agnès b. en... Lire la suite

    Par  La Fille Aux Chaussures
    BONS PLANS, CONSO, CÔTÉ FEMMES, MÉDIAS, MODE, MODE FEMME, PRESSE ÉCRITE
  • B comme...

    comme...

    bac - baccalauréat - baiser - banc - bande - bande dessinée - bande annonces - banlieue - banque - banque mondiale - baptême - barbe - baril - bas - bataille -... Lire la suite

    Par  Babylonezoo
    A CLASSER

A propos de l’auteur


Jibaku 14 partages Voir son profil
Voir son blog