Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Item in TList ändern / aktualisieren (https://www.delphipraxis.net/84987-item-tlist-aendern-aktualisieren.html)

Luckie 24. Jan 2007 11:10


Item in TList ändern / aktualisieren
 
Ich habe eine Liste mit Objekten. Wie kann ich in dieser Liste ein Objekt jetzt aktualisieren, weil es sich geändert hat? Ich habe mir da bisher so was gebaut:
Delphi-Quellcode:
procedure TPageCollection.Update(Index: Integer; Item: TImageEnVect);
begin
  self.Delete(Index);
  self.Insert(Index, Item);
end;
Aber was passiert da mit dem Speicher? Geht das so in Ordnung oder habe ich mir da gerade ein Speicherleck gebaut?

Zum Schluss freigegeben werden die Objekte so:
Delphi-Quellcode:
destructor TPageCollection.Destroy;
var
  i: Integer;
begin
  for i := 0 to self.Count - 1 do
  begin
    self.Items[i].Parent.RemoveControl(self.Items[i]);
    self.Items[i].Free;
  end;
  inherited;
end;

SirThornberry 24. Jan 2007 11:34

Re: Item in TList ändern / aktualisieren
 
Natürlich musst du das Object auch freigeben wenn du den Pointer aus der Liste wirfst und sonst keine Referenz mehr drauf hast. Aber anstelle von Delete + Insert kannst du auch einfach das Item ersetzen über das Property Items

Luckie 24. Jan 2007 11:44

Re: Item in TList ändern / aktualisieren
 
Das wäre natürlich eine Idee. Meine Klasse sieht jetzt so aus:
Delphi-Quellcode:
type
  TPageCollection = class(TList)
  private
    function GetItem(Index: Integer): TImageEnVect;
    procedure SetItem(Index: Integer; Item: TImageEnVect);
  public
    // ...;
    property Items[Index: Integer]: TImageEnVect read GetItem write SetItem;
    // ...;
  end;

// ...;

function TPageCollection.GetItem(Index: Integer): TImageEnVect;
begin
  Result := inherited Get(Index);
end;

procedure TPageCollection.SetItem(Index: Integer; Item: TImageEnVect);
begin
  self.Items[Index] := Item;
end;

procedure TPageCollection.Update(Index: Integer; Item: TImageEnVect);
begin
  self.Items[Index] := Item;
end;
Aber dann reagiert das Programm gar nicht mehr.

Muetze1 24. Jan 2007 11:47

Re: Item in TList ändern / aktualisieren
 
Zitat:

Zitat von Luckie
Aber dann reagiert das Programm gar nicht mehr.

Endlosschleife, da dein SetItem mit Self.Items[] wieder die SetItem aufruft...

Delphi-Quellcode:
procedure TPageCollection.SetItem(Index: Integer; Item: TImageEnVect);
begin
  Inherited Items[Index] := Item;
end;
So sollte es klappen. Und Update() macht ja eindeutig das gleiche wie SetItem() bzw. die Zuweisung auf Items[], daher kann man die o.g. Kurzform nutzen.

SirThornberry 24. Jan 2007 11:49

Re: Item in TList ändern / aktualisieren
 
Du solltest im SetItem den Speicher des Objectes auch freigeben bevor du einen neuen Zeiger in die Liste schreibst und der alte Zeiger weg ist und niemand mehr auf den Reservierten Speicher zugreifen kann um diesen frei zu geben.

Luckie 24. Jan 2007 12:00

Re: Item in TList ändern / aktualisieren
 
Also so:
Delphi-Quellcode:
procedure TPageCollection.Insert(Index: Integer; Item: TImageEnVect);
begin
  self.Items[Index].Free;
  inherited Items[Index] := Item;
end;

procedure TPageCollection.Update(Index: Integer; Item: TImageEnVect);
begin
  self.Items[Index] := Item;
end;
Besten Dank für eure Hilfe.

Muetze1 24. Jan 2007 12:00

Re: Item in TList ändern / aktualisieren
 
Zitat:

Zitat von SirThornberry
Du solltest im SetItem den Speicher des Objectes auch freigeben bevor du einen neuen Zeiger in die Liste schreibst und der alte Zeiger weg ist und niemand mehr auf den Reservierten Speicher zugreifen kann um diesen frei zu geben.

Entweder direkt da, oder einfach von TList die Notify Methode nutzen. Siehe dazu auch hier als Beispiel

Notify wird auch korrekt für jedes Element beim Clear aufgerufen. Und das geschieht übrigens auch beim Destructor von TList für die Items. Daher wäre bei Notify auch deine Schleife im Destructor hinfällig.

Luckie 24. Jan 2007 12:06

Re: Item in TList ändern / aktualisieren
 
Das habe ich schon ausprobiert, da hat es bei mir aber gekracht. Mal sehen, ob das jetzt mit dem neuen Code geht. Ah, der letzte Satz war es wohl, denn den Destruktor hatte ich noch nicht rausgenommen gehabt, wessewegen er wohl Objekte Freigeben wollte, die schon freigegeben wurden.

:thumb:


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:10 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz