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.