Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Object aus einer TList löschen (https://www.delphipraxis.net/86933-object-aus-einer-tlist-loeschen.html)

Luckie 21. Feb 2007 11:09


Object aus einer TList löschen
 
Îch habe Objekte in einer Liste vom Typ TList. Jetzt soll ein Objekt aus dieser Liste gelöscht werden. Dies mache ich erstmal so:
Delphi-Quellcode:
  inherited Delete(Index);
  Self.Items[Index].Free;
  Self.Items[Index] := nil;
Jetzt habe ich aber eine Lücke in meiner Liste, da die Reihenfolge erhalten bleiben muss, müsste ich ja jetzt alle nachfolgenden Objekte eins aufrücken lassen in der Liste. Oder sehe ich das falsch? Wenn meine Annahme richtig ist, wie mache ich das?

Mache ich es so:
Delphi-Quellcode:
  for i := Index to Self.Count - 1 do
  begin
    Self.Items[Index] := Self.Items[Index + 1];
  end;
laufe ich ja über die Anzahl der Objekte in der Liste hinaus und ich bekomme eine AV.

Christian Seehase 21. Feb 2007 11:15

Re: Object aus einer TList löschen
 
Moin Michael,

Zitat:

Zitat von Luckie
Jetzt habe ich aber eine Lücke in meiner Liste, da die Reihenfolge erhalten bleiben muss, müsste ich ja jetzt alle nachfolgenden Objekte eins aufrücken lassen in der Liste. Oder sehe ich das falsch?

Ja.

Zitat:

Zitat von OH - TList - Delete
Calling Delete moves up all items in the Items array that follow the deleted item, and reduces the Count.


Luckie 21. Feb 2007 11:17

Re: Object aus einer TList löschen
 
Hm, dann muss mein Fehler wo anders liegen. Danke für den Hinweis.

Ist das so in Ordnung:
Delphi-Quellcode:
procedure TPageCollection.Delete(Index: Integer);
begin
  Self.Items[Index].Free;
  Self.Items[Index] := nil;
  inherited Delete(Index);
  Self.Rename;
end;
Erst das Objekt freigeben und dann den Item aus der Liste löschen? Mache ich es anders rum, bekomme ich im weiteren Programmverlauf eine AccessViolation.

Muetze1 21. Feb 2007 11:18

Re: Object aus einer TList löschen
 
Dein Delete ist falsch implementiert, denn: Das inherited Delete löscht das entsprechende Element und verkürzt die Liste. Somit gibst du mit .Free nach dem inherited Aufruf das nachgerückte Element frei. Wenn du das letzte Element löscht sogar ein nicht existierendes, etc. Damit baust du dir selber eine nicht existierende Instanz in deine Liste.

Wenn du ein Element aus einer TList haben willst ohne de Index freizugeben, dann nimm ihn einfach mit Items und weise Nil zu. Ansonsten bei TObjectList gibt es auch ein entsprechendes Extract().

Nochwas: Wenn du Nil Einträge in deiner TList (oder Nachfahre) hast, dann kannst du dir einfach mit der Methode Pack entfernen lassen.

/-------- roter Kasten --------

Das "Ja" (von Christian Seehase) ist falsch: Luckie fragt, ob er die Items nachrücken muss. Dem ist nicht so, TList macht dies. Daher trotzdem abgeschickt...

/EDIT2: Korrektur zu der Schleife: Wenn du sie brauchen tätest, was hier ja erklärterweise nicht der Fall ist, dann müsste die Schleife theoretisch nur bis Count-2 laufen, da du schliesslich mit Index+1 immer den Nachfolger holst. Diese darf somit auch nicht Count-1 überschreiten, daher nochmals -1, da dem +1 Rechnung getragen werden muss.

Delphi-Quellcode:
for i := Index to Self.Count - 2 do
  begin
    Self.Items[Index] := Self.Items[Index + 1];
  end;

Luckie 21. Feb 2007 11:26

Re: Object aus einer TList löschen
 
Push. Habe noch was ergänzt.

Ferber 21. Feb 2007 11:27

Re: Object aus einer TList löschen
 
Hi !
So sollte es gehen
Delphi-Quellcode:
var p:Pointer;
begin
  p:=Liste.Items[Index];
  FreeAndNil(p);
  Liste.Delete(Index);
end;

Luckie 21. Feb 2007 11:32

Re: Object aus einer TList löschen
 
Ja gut, das wäre jetzt die elegante Kurzfassung von meinem Code. ;)

marabu 21. Feb 2007 11:33

Re: Object aus einer TList löschen
 
Hallo Michael,

wenn in deinem ersten Beitrag TCollection statt TList stehen würde, dann würde dein thread mehr Sinn für mich machen.

Freundliche Grüße

Luckie 21. Feb 2007 11:35

Re: Object aus einer TList löschen
 
In der Liste befinden sich aber keine Nachfahren von TCollectionItem. Die Klasse TCollection kann ich also nicht benutzen, wenn ich das richtig sehe. Desweiteren haben wir ja eine Lösung gefunden.

Muetze1 21. Feb 2007 11:39

Re: Object aus einer TList löschen
 
1. Ein free reicht völlig.
2. Ein Nil setzen muss nicht sein, der Eintrag fliegt eh raus. Du hast ja ein TList Nachkommen und keinen TObjectList Nachkommen, der selber versuchen würde das zu entfernende Element zu löschen (was beim zuweisen von Nil auf einen Item auch geschehen würde).

Daher:

Delphi-Quellcode:
var lObj: TObject;
begin
  lObj := Liste.Items[Index];
  Liste.Delete(Index);
  lObj.Free;  // kann genauso gut vor dem Delete() stehen, das ist Schnuppe...
end;
Bzw. Luckies Version:

Delphi-Quellcode:
procedure TPageCollection.Delete(Index: Integer);
begin
  Self.Items[Index].Free;
  inherited Delete(Index);
  Self.Rename;
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:44 Uhr.
Seite 1 von 2  1 2      

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