Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi TObjectlist und der Seitenwechsel (https://www.delphipraxis.net/200812-tobjectlist-und-der-seitenwechsel.html)

peterbelow 28. Mai 2019 21:15

AW: TObjectlist und der Seitenwechsel
 
Zitat:

Zitat von Delbor (Beitrag 1433285)
Delete oder Clear entfernen nur die Objekte aus der Liste, zerstören sie aber nicht, zumindest, wen ich das Emba-Wicki richtig verstanden habe.

Das hast Du nicht ganz richtig verstanden. Das Verhalten der Liste wird von der OwnsObjects-Eigenschaft gesteuert. Wenn die True ist zerstört die Liste die enthaltenen Objekte, wenn sie aus der Liste entfernt werden, also genau das, was Du haben willst. Was Du im Zitat oben geschrieben hast gilt, wenn OwnsObjects False ist.

Delbor 29. Mai 2019 06:58

AW: TObjectlist und der Seitenwechsel
 
Hi peterbelow
Zitat:

Zitat von peterbelow (Beitrag 1433309)
Zitat:

Zitat von Delbor (Beitrag 1433285)
Delete oder Clear entfernen nur die Objekte aus der Liste, zerstören sie aber nicht, zumindest, wen ich das Emba-Wicki richtig verstanden habe.

Das hast Du nicht ganz richtig verstanden. Das Verhalten der Liste wird von der OwnsObjects-Eigenschaft gesteuert. Wenn die True ist zerstört die Liste die enthaltenen Objekte, wenn sie aus der Liste entfernt werden, also genau das, was Du haben willst. Was Du im Zitat oben geschrieben hast gilt, wenn OwnsObjects False ist.

Ich hab das bisher immer so verstanden, dass TObjectList bei OwnsObject := true; seine Items nur zerstört, wenn sie selbst zerstört wird. Man lernt nie aus!

Gruss
Delbor

hoika 29. Mai 2019 07:06

AW: TObjectlist und der Seitenwechsel
 
Hallo,
Zitat:

wenn die True ist zerstört die Liste die enthaltenen Objekte, wenn sie aus der Liste entfernt werde
das macht ja keinen Sinn.

Das würde ja Speicherlecks erzeugen.


OwnsObject = mir gehört das Objekt.

Mache ich ein Delete(0), erwarte ich

1. Das Objekt wird freigegeben
2. der Listeneintrag wird freigegeben (die Liste wird also um 1 kleiner)


Aber: Gut das wir darüber geredet haben ;)

peterbelow 29. Mai 2019 12:04

AW: TObjectlist und der Seitenwechsel
 
Zitat:

Zitat von hoika (Beitrag 1433329)
Hallo,
Zitat:

wenn die True ist zerstört die Liste die enthaltenen Objekte, wenn sie aus der Liste entfernt werde
das macht ja keinen Sinn.

Das würde ja Speicherlecks erzeugen.

Wie kommst Du denn da drauf? Wenn man eine TObjectlist mit OwnsObject = true erzeugt will man damit erreichen, dass die Liste die Lebensdauer der hinzugefügten Objekte verwaltet und man sich nicht mehr selbst darum kümmern muss. Das ist wie das Owner-Konzept bei TComponent & Cie.
Wenn man die Liste leert, zerstört oder einen einzelnen Eintrag mit Delete entfernt ruft die Liste für die betroffenen Objekte Free auf, also kein Leck. Wenn man eines der Objekte in der Liste selbst zerstört bleibt in der Liste eine ungültige Referenz zurück, die später meist zu einer Exception führt. Wenn man ein Objekt zurückhaben will muss man die Extract-Methode verwenden und nicht Delete oder Remove; damit übernimmt man dann auch die Verwaltung der Lebensdauer wieder.

Delbor 29. Mai 2019 19:01

AW: TObjectlist und der Seitenwechsel
 
Hi zusammen
Ich behaupte mal: Hoika hat recht. Das Embarcadero Wiki zu TObjectlist.Ownsobject:
Zitat:

Ermittelt oder setzt den Eigentümer des Objekts.

OwnsObjects ermittelt oder legt fest, ob die Liste Eigentümer der Objekte in der Liste ist. Wenn die Liste zum Zeitpunkt des Entfernens des Eintragsobjekts aus der Liste Eigentümer der Einträge ist, wird das Eintragsobjekt freigegeben. Create initialisiert diese Eigenschaft.
Es stellt sich jetzt halt die Frage, was der fett formatierte Satz nun wirklich heisst. Tatsache ist, dass bei einem Delete eines bestimmten Eintrags dieser aus der Liste entfernt wird, und zwar unabhängig davon, ob OwnsObjects nun False oder True ist. Nun suggeriert aber der bewusste Satz, dass bei True das Eintragsobjekt freigegeben wird, also ein "Eintragsobject.Free" durchgeführt wird.
Technisch wäre dies wohl möglich, wenn die Objectlist alle damit zusammenhängenden Propertys und deren Felder aktualisieren würde. Nebst dem Count-Property würde dies wohl auch Capacity betreffen. Würde... Aber:
An dieser Stelle wollte ich eigentlich die Stelle aus dem Embarcadero Wiki zitieren, die ich heute morgen gelesen hatte, jetzt aber nicht mehr finden kann. Da wurde darauf hingewiesen, dass man das Ereignis OnNotify verwenden solle, um das Objekt nicht nur aus der Liste zu entfernen, sondern wirklich freizugeben/zu zerstören. Gefunden habe ich stattdessen:

Mein Fazit: Beide, hoika sowohl peterbelow haben recht - die nicht generische Liste verlangt einfach etwas mehr Handarbeit.
Wie das nun wirklich ist, kann nur ein Studium / durchsteppen durch die Sourcen geben.

Gruss
Delbor

DeddyH 29. Mai 2019 20:16

AW: TObjectlist und der Seitenwechsel
 
Wenn ein Eintrag aus der Liste entfernt wird, wird intern ein Notify-Event gefeuert, das muss dich aber gar nicht interessieren. Ist die Liste Eigentümer ihrer enthaltenen Objekte, wird das zu entfernende Objekt auch freigegeben.

peterbelow 30. Mai 2019 12:51

AW: TObjectlist und der Seitenwechsel
 
Zitat:

Zitat von Delbor (Beitrag 1433413)
Hi zusammen
Ich behaupte mal: Hoika hat recht. Das Embarcadero Wiki zu TObjectlist.Ownsobject:
Zitat:

Ermittelt oder setzt den Eigentümer des Objekts.

OwnsObjects ermittelt oder legt fest, ob die Liste Eigentümer der Objekte in der Liste ist. Wenn die Liste zum Zeitpunkt des Entfernens des Eintragsobjekts aus der Liste Eigentümer der Einträge ist, wird das Eintragsobjekt freigegeben. Create initialisiert diese Eigenschaft.
Es stellt sich jetzt halt die Frage, was der fett formatierte Satz nun wirklich heisst. Tatsache ist, dass bei einem Delete eines bestimmten Eintrags dieser aus der Liste entfernt wird, und zwar unabhängig davon, ob OwnsObjects nun False oder True ist. Nun suggeriert aber der bewusste Satz, dass bei True das Eintragsobjekt freigegeben wird, also ein "Eintragsobject.Free" durchgeführt wird.

Und genau das passiert auch, sowohl in TObjectlist als auch bei TObjectlist<T>. Dieser Notification-Mechanismus wird von TObjectlist vom Elter TList geerbt und überschrieben, um das Verhalten bei OwnsObjects = true zu implementieren. Da muss der Programmierer nichts mehr nachflicken, das ist alles schon geregelt.

OnNotify muss man sich nur antun, wenn man TList oder TList<T> verwendet und die Lebensdauer der Items in der Liste nicht anderswo verwaltet.

Delbor 30. Mai 2019 16:18

AW: TObjectlist und der Seitenwechsel
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hi zusammen

Danke für eure Antworten! In Bezug auf die generische Liste steht das ja so in der Help - ich war mir nur nicht sicher, ob ich das richtig verstanden habe. Inzwischen habe ich die entsprechende Unit in meinem Projekt geöffnet und einen Haltepunkt gesetzt, so quasi für die letzte Bestätigung. Bei der nichtgenerischen Liste werde ich dies allerdings nicht tun, sondern einfach glauben, dass es so ist, da ich die ich eh nie verwenden werde.
Inzwischen hat sich aber ein neues "Problem" ergeben. In der folgenden Prozedur lösche ich alle TPdfViews aus der Liste, wenn ich eine neue PDF öffne:
Delphi-Quellcode:
procedure TRogersPdfFrame.DeletePdfListObjects;
  var i: Integer;
begin
  i := 0;
  HomeOfficerMainForm.EdiBeforeDelete.Text := 'BeforeDelete: '+ IntToStr(FPdfList.Count);
  while i <= FPdfList.Count-1 do
  begin
    if FPdfList.Items[i].Active then
    begin
      FPdfList.Items[i].Active := False;
      FPdfList.Delete(i);
    end;
    inc(i);
  end;
  HomeOfficerMainForm.EdiAfterDelete.Text := 'AfterDelete : '+ IntToStr(FPdfList.Count);
end;
Die Anweisungen an die Edits 'EdiBeforeDelete' und 'EdiAfterDelete' dienten mir zur Kontrolle, da ich mir erst nicht sicher war, dass auch alle TPdfViews(die Items der Liste) gelöscht werden. Der Wert von 'EdiBeforeDelete' ist dabei immer 1, unabhängig davon, wie gross FPdfList.Count tatsächlich ist. Der andere Wert ist 0.
Ich hab das gerade nochmal getestet. Dabei ist mir Delphi eiingefroren, und ich musste das Ding mit dem Taskmanager abschiessen. Nachdem ich das erste mal ein neues PDF geöffnet hatte:
Anhang 51171
Anschliessend versuchte ich nochmal, eine neue PDF zu öffnen - abschuss. *
In der Listbox links eben dem Pdf trage ich jedesmal, wenn ich ein neues PDFView erzeuge, dessen Namen ein. Die ist also korrekt.

Kurz, bevor ich Delphi abschiessen musste, viel mir auf, dass das Edit 'EdiBeforeDelete' den Wert 3 anzeigte...

Gruss
Delbor

PS: Das mit dem Abschuss hielt ich erst für ziemlich 'mysteriös', habmir dann jedoch die drei nächsthöheren PDFs mal angesehen. Die sind zwischen knappen 6000 und guten 30'000 kb gross. Ich hätte Delphi also wohl nicht abschiesssen müssen, sonder nur noch etwas Geduld haben müssen. Oder in Zukunft begindoc und enddoc einbauen...

peterbelow 31. Mai 2019 12:20

AW: TObjectlist und der Seitenwechsel
 
Zitat:

Zitat von Delbor (Beitrag 1433518)
Hi zusammen

Danke für eure Antworten! In Bezug auf die generische Liste steht das ja so in der Help - ich war mir nur nicht sicher, ob ich das richtig verstanden habe. Inzwischen habe ich die entsprechende Unit in meinem Projekt geöffnet und einen Haltepunkt gesetzt, so quasi für die letzte Bestätigung. Bei der nichtgenerischen Liste werde ich dies allerdings nicht tun, sondern einfach glauben, dass es so ist, da ich die ich eh nie verwenden werde.
Inzwischen hat sich aber ein neues "Problem" ergeben. In der folgenden Prozedur lösche ich alle TPdfViews aus der Liste, wenn ich eine neue PDF öffne:

Wenn Du in einer Schleife etwas aus einer Liste löscht sollte die Schleife immer vom Ende der Liste rückwärts laufen. Schließlich ändert der Löschvorgang nicht nur die Zahl der Einträge in der Liste sondern auch die Indices aller Einträge nach dem gelöschten.

Ersetze die While-Schleife einfach durch

Delphi-Quellcode:
 for i := FPdfList.Count-1 downto 0
  begin
    if FPdfList.Items[i].Active then
    begin
      FPdfList.Items[i].Active := False;
      FPdfList.Delete(i);
    end;
  end;
anfangen und am Ende Dec(i) anstelle von Inc(i) verwenden. Oh, un der


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:11 Uhr.
Seite 2 von 2     12   

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