Différences et utilisation de TList et TObjectList

Unités concernées

TList(Classes.pas)

TObjectList(Contnrs.pas)

Création d'objets TObjectList

Le constructeur de TObjectList accepte un paramètre : constructor TObjectList.Create(AOwnsObjects: Boolean). Son signification est explicite : indique si la liste possède les objets qu'elle contient.

Documentation officielle

Si la propriété OwnsObjects est définie sur true (par défaut), TObjectList gère la mémoire de ses objets, libérant un objet lorsque son index est réassigné; lorsqu'il est supprimé de la liste avec les méthodes Delete, Remove ou Clear; ou lorsque l'instance TObjectList elle-même est détruite. Cette explication indique que les méthodes de suppression et de libérationn de TObjectList sont influencées par le paramètre AOwnsObjects. Avec la valeur par défaut, les objets de la liste sont libérés lors de la destruction de l'ObjectList.

TObjectList = Classe (TList); TObjectList hérite de Tlist, et comme son nom l'indique, elle est spécifiquement conçue pour la gestion de listes d'objets. Quelles fonctionnalités supplémentaires apporte-t-elle ? Tout d'abord, TObject permet une utilisation simplifiée des objets sans nécessité de conversions de pointeurs. Elle enrichit la méthode Notify pour gérer les états actuels, comme la suppression qui entraîne également le nettoyage des références concernées;

procedure TObjectList.Notify(Element: Pointer; Action: TListNotification);
begin
     if (Action = lnDeleted) and OwnsObjects then
        TObject(Element).Free;

     inherited Notify(Element, Action);
end;

On observe dans la méthode Notify que lorsque TObjectList.OwnsObjects=True (valeur par défaut), la libération s'accompagne de la destruction des objets conteuns. Lorsque TObjectList.OwnsObjects=False, seuls les éléments de la liste sont supprimés, pas les objets eux-mêmes. Dans Tlist, la méthode Clear() appelle SetCount et SetCapacity ; cela supprime tous les éléments.

procedure TList.Clear(); 
begin
     SetCount(0);
     SetCapacity(0);
end;

Lorsque l'objet est détruit, Clear() est automatiquement appelé pour vider la liste.

destructor TList.Destroy;
begin
   Clear();
end;

Toute classe héritant de Tlist doit implémenter Notify() pour faciliter la libération des ressources et éviter les problèmes. Les différences de libération entre List et ObjectList sont illustrées dans l'exemple suivant :

 1 procedure TForm1.Bouton1Click(Sender: TObject);
 2 var
 3  listeObjets: TObjectList;
 4  compteur: Integer;
 5  bouton: TButton;
 6 begin
 7   listeObjets := TObjectList.Create;
 8   for compteur := 0 to 6 do
 9   begin
10      bouton := TButton.Create(Self);
11      with bouton do begin
12        Caption := Format('Bouton %d', [compteur+1]);
13        Parent := Self;
14      end;
15      listeObjets.Add(bouton);
16    end;
17    ShowMessage('La destruction de TObjectList libère aussi les objets qu''il contient');
18    listeObjets.Free;
19 end; 
20 
21 procedure TForm1.Bouton2Click(Sender: TObject);
22 var
23   listeSimple: TList;
24   compteur: Integer;
25   bouton: TButton;
26 begin
27   listeSimple := TList.Create;
28   for compteur := 0 to 6 do
29   begin
30      bouton := TButton.Create(Self);
31      with bouton do 
32      begin
33         Caption := Format('Bouton %d', [compteur+1]);
34         Parent := Self; 
35      end;
36      listeSimple.Add(bouton);
37   end; 
38   ShowMessage('Après libération de TList, les objets restent en mémoire');
39   listeSimple.Free;
40 end;

Si vous utilisez TObjectList pour le stockage, soyez conscient que l'appel de la méthode sort nécessite de définir d'abord ownerobject sur False

Une autre classe intéressante que nous avons tous utilisée est TStringList, qui possède une méthode AddObject permettant de manipuler des objets de manière similaire à TObjectList.

En résumé : pour gérer une collection d'objets, il est préférable d'hériter de TObjectList, qui offre un mécanisme de gestion des ressources robuste et complet.

Étiquettes: Delphi TObjectList TList Gestion Mémoire programmation objet

Publié le 17 juin à 21h31