Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Delphi Discussion :

TObjectList : Comment l'utiliser ?


Sujet :

Delphi

  1. #1
    Candidat au Club
    TObjectList : Comment l'utiliser ?
    Salut à tous,
    je vous prix de bien vouloir m'expliquer qu'est-ce que TObjectList et comment l'utiliser ?

    merci infiniment !

  2. #2
    Expert éminent sénior
    Comme une TStringList mais au lieu de chaine, tu as des objets, et avant de venir ici tu fais F1, c'est pas difficile comme objet

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    Machin := TTruc.create();
    List.Add(Machin);
    Bidule := TTruc(List.items[...]).Chose
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre éclairé
    Et pour compléter, l'avantage de TObjectList c'est qu'il gère en interne la liberation des objets.

  4. #4
    Modérateur

    avec OwnsObjects=True : c'est très pratique et permet de faire un peu GarbageCollector !
    Delphi 5 Pro - Delphi 10.3.2 Rio Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  5. #5
    Membre expérimenté
    Une autre utilisation intéressante est de créer une liste avec des objets typés :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    uses Contnrs;
     
    type
      TTruc = class
      public
        libelle : string;
        constructor Create(pLibelle : string);
      end;
     
      TListeDeTrucs = class(TObjectList)
      private
        function GetItem(Index: Integer): TTruc;
        procedure SetItem(Index: Integer; const Value: TTruc);
      public
        function Add(AObject: TTruc): Integer;
        procedure Insert(Index: Integer; AObject: TObject);
        // idéalement, redéfinir toutes les méthodes qui renvoient un TObject
        property Items[Index: Integer]: TTruc read GetItem write SetItem; default;
      end;
     
    { TTruc }
     
    constructor TTruc.Create(pLibelle: string);
    begin
      libelle := pLibelle;
    end;
     
    { TListeDeTrucs }
     
    function TListeDeTrucs.Add(AObject: TTruc): Integer;
    begin
      result := inherited Add(AObject);
    end;
     
    procedure TListeDeTrucs.Insert(Index: Integer; AObject: TObject);
    begin
      inherited Insert(index, AObject);
    end;
     
    function TListeDeTrucs.GetItem(Index: Integer): TTruc;
    begin
      result := TTruc(inherited GetItem(index));
    end;
     
    procedure TListeDeTrucs.SetItem(Index: Integer; const Value: TTruc);
    begin
      inherited setItem(index, value);
    end;


    Utilisation :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    var
      l : TListeDeTrucs;
      i : integer;
    begin
      l := TListeDeTrucs.Create(true);
      l.Add(TTruc.Create('coucou'));
      l.Add(TTruc.Create('titi'));
      l.Add(TTruc.Create('toto'));
      for i := 0 to l.count - 1 do
        showMessage(l.items[i].libelle);
      l.Free;
    end;


    Bloon
    A lire : Les règles du club
    Delphi : La FAQ - Articles

  6. #6
    Expert confirmé
    Citation Envoyé par tourlourou
    avec OwnsObjects=True : c'est très pratique et permet de faire un peu GarbageCollector !
    C'est vrai que c'est pratique que la liste se charge de détruire ses composants.
    Je l'utilise souvent.

    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. Écrivez dans un français correct !!

    Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.3.2 Entreprise
    OpenGL 2.1 - Oracle 10g - Interbase (7 - XE) - PostgreSQL 11.6

  7. #7
    Modérateur

    Salut,

    Q : qu'est-ce que TObjectList

    R : Comme une TStringList mais au lieu de chaine, tu as des objets
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  8. #8
    Expert éminent sénior
    Ouais, je trouvais que sa question démontrait une absence de recherche personnelle, en plus ce que j'ai écrit est n'est pas exacte, une TStringList c'est une liste de chaine auquel on peut associé des objets, donc c'est encore plus poussé que la TObjectList que l'on peut retrouver d'ailleurs dans les listes Components et Controls ...

    Je remercie Bloon d'avoir implémenté le TTRuc
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  9. #9
    Modérateur

    Re-Salut,

    Q : qu'est-ce que TObjectList

    R : Comme une TStringList mais au lieu de chaine, tu as des objets
    Pourquoi "au lieu de chaine" : Je dirais plus exactement qu'une TStringList peut contenir à la fois des chaines ET des objets en utilisant directement l'instruction ma_liste.AddObject('chaine',objet) alors que pour associer un libellé-chaine à un objet avec le TObjectList il faut ajouter du code.

    De plus comme la chaine et l'objet ont le même indice dans la TStringList on peut retrouver directement l'indice avec ma_liste.Find('chaine' ... et/ou ma_liste.IndexOf('chaine' ... ou ma_liste.IndexOfObject(objet) puis en utilisant cet indice on peut accéder directement aux objects avec la propriéte Objects : Exemple avec un bitmap comme objet : Canvas.draw(20,20,tBitMap(ma-liste.Objects[i]));

    Et en prime avec ma_liste.Sort on peut classer les chaînes de la liste en ordre croissant.

    Et pour terminer la libération finale se fait par un simple ma_liste.free.

    En fait il faudrait rebaptiser les TStringList en TStringAndObjectsList histoire d'appeler un chat un chat.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  10. #10
    Expert éminent sénior
    Pour le TreeView, on a Node.Data

    Et pour terminer la libération finale se fait par un simple ma_liste.free.
    Euh, les Objets d'une TStringList doivent être explicitement libéré contrairement au Object ajouté dans une TObjectList avec OwnsObjects à True (Par Défaut !)
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  11. #11
    Modérateur

    mon message de 14h04 était incomplet ... mais le temps d'achever le suivant à 15h06 vous aviez déjà réagi ... donc mille excuses s'il y a redondance avec le vôtres.

    Par contre comme je mets les TStringList un peu à toutes les sauces je n'ai pas encore trouvé l'intérêt réel du TObjectList.

    Avec TStringList on peut faire beaucoup de choses avec peu de lignes de code alors qu'avec TObjectList j'ai l'impression qu'il faut beaucoup de lignes de code pour faire peu de choses ... non???
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  12. #12
    Modérateur

    Euh, les Objets d'une TStringList doivent être explicitement libéré
    Exact, car ma_liste.free met seulement fin à l'existance du tableau dynamique de pointeurs ce qui détruit uniquement les chaines.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  13. #13
    Expert éminent sénior
    Je l'utilise assez peu, on a plus souvent des TStringList dans des ListBox ou autre, et j'utilise souvent la propriétés objects...

    ensuite, la TObjectList, est souvent remplacer par une collection, ou sinon, j'utilise bcp de TComponent, que j'appele genre TBiduleManager, ça contient plein de méthode de classe (un singleton est utilisé en interne) et ça gère souvent comme Owner d'un ensemble de Bidule, j'utilise le TComponent surtout pour le Owner et le published, si je n'ai pas besoin de publication, j'utilise une TObjectList mais c'est rare, car je passe souvent alors par une TList et Pointer de Structure (je fais de faux objet souvent)

    alors la TStringList on l'utilise tel que avec un composant VCL, la TObjectList souvent on l'a surcharge pour éviter les transtypages des objets si la liste ne contient que de TBidule ...

    je n'ai que deux codes sur quelques millions de ligne que j'ai écrit (en 7 ans) qui utilise une TObjectList, lol, et je m'en sert soit comme garbage collector uniquement soit parce que j'ai pas une le temps de faire une TCollection ^_^

    En fait, je vois pas mal de code où au lieu d'utiliser une TObjectList j'ai pris une TList car de toute façon faut caster l'Object ou le Pointer en Objet Typé exploitable et ça dans des objets genre TXMLNode, THierarchieNode, TFindPathNode (algo de recherche de chemin), ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  14. #14
    Modérateur

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    je m'en sert soit comme garbage collector uniquement, soit


    C'est quoi cet usage de "Collecteur de détritus" ? Je pige mal cette image.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  15. #15
    Expert éminent sénior
    Le "Garbage Collector" c'est un concept Java, tu créés tes objets mais tu ne les libères jamais explicitement, la machine virtuelle sait quand elle doit libérer et le pré-compilo fait déjà du nettoyage lorsqu'il génère les. class puisqu'un objet ne peut pas survivre en dehors du bloc de déclaration (en java tu peux déclarer un peu partout c'est comme si en delphi tu pouvais mettre var à chaque begin ...

    Voici un code qui illustre parfaitement ce cas

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
       edtimport.Text := GetPub_eXistenZ('TIMER', 'IMPORT', '12', TIniSpy.Create(IniSpyManager, edtimport));
       edtexport.Text := GetPub_eXistenZ('TIMER', 'EXPORT', '12', TIniSpy.Create(IniSpyManager, edtexport));
       edDelaiValide.Text := GetPub_eXistenZ('DELAI', 'VALIDE', '30', TIniSpy.Create(IniSpyManager, edDelaiValide));
       edDelaiNonValide.Text := GetPub_eXistenZ('DELAI', 'NONVALIDE', '90', TIniSpy.Create(IniSpyManager, edDelaiNonValide));


    ... j'ai comme cela, plus de 40 Objet créé, ... au lieu de me prendre la tête à gérer la libération d'objet le constructeur c'est ceci

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    constructor TIniSpy.Create(AManager: TIniSpyManager; AControl: TControl);
    begin
       inherited Create();
     
       FControl := AControl;
       AManager.Add(Self);
    end;


    à un moment j'ai mis ce qui suit dans le Create de la Form

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
      IniSpyManager := TIniSpyManager.Create();


    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
       TIniSpyManager = class(TObjectList)
       private
          procedure CreateVisualSpy(const SpyIndex: Integer);
       public
          procedure CheckSpy(Show: Boolean);
       end;


    et à la libération de la form

    j'ai

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    IniSpyManager.Free();


    Comme c'est une ObjectList, par défaut sa libération cela libère les objets, c'est le même principe quand tu fais "TEdit.Create(Self);" le Owner libére le Edit ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  16. #16
    Membre éclairé
    Et pour terminer la libération finale se fait par un simple ma_liste.free.
    C'est quoi cet usage de "Collecteur de détritus" ? Je pige mal cette image.
    ma_liste est une tstringlist. Free supprime les entrées dans la liste mais ne libére pas les objets associées. Leur libération doit être explicite et codée par le programmeur contrairement à la TObjectList qui a la faculté à l'instars d'un ramasse miette de gérer la libération des objets qui lui sont confiés.

    Ce concept de garbage collector a été repris sous le framework dotnet et est pris en charge par le clr.

  17. #17
    Modérateur

    Merci à tous les deux.

    Pigé. En fait vous appelez par "collector de détritus" ou par "ramasse miettes" un truc qui nous laisse créer des objets et qui nous libère de la corvée de nettoyage en le faisant à notre place.

    Donc un "+" pour la TObjectList que TStringlist n'a pas.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

###raw>template_hook.ano_emploi###