Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - Dynamisch erzeugte Komponenten mit Parent - diese freigeben?


galagher - Mo 12.10.20 17:16
Titel: Dynamisch erzeugte Komponenten mit Parent - diese freigeben?
Hallo!

Ich erzeuge zur Laufzeit mehrere Komponenten auf einer ScrollBox, deren Parent jeweils diese ScrollBox ist.
Muss ich beim Beenden des Programms alle diese Komponenten mit .Free zerstören oder wird das automatisch erledigt? Da die Komponenten die ScollBox als Parent haben, muss ich sie natürlich nicht freigeben, oder? Ich bin mir da nicht so ganz sicher! :?!?:


Moderiert von user profile iconNarses: Topic aus Delphi Language (Object-Pascal) / CLX verschoben am Mo 12.10.2020 um 21:50


jaenicke - Mo 12.10.20 18:54

user profile icongalagher hat folgendes geschrieben Zum zitierten Posting springen:
Muss ich beim Beenden des Programms alle diese Komponenten mit .Free zerstören oder wird das automatisch erledigt? Da die Komponenten die ScollBox als Parent haben, muss ich sie natürlich nicht freigeben, oder? Ich bin mir da nicht so ganz sicher! :?!?:
Du verwechselst gerade Parent und Owner. Parent ist die Fläche, auf der das Control liegt. Owner ist der Besitzer, der sich dann auch um die Freigabe kümmert. Wenn du eine Komponente mit ....Create(ScrollBox) erzeugst, sprich die Scrollbox als Owner dem Konstruktor übergibst, gehören sie der Scrollbox und eine manuelle Freigabe ist nicht erforderlich.


galagher - Mo 12.10.20 19:51

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Du verwechselst gerade Parent und Owner. Parent ist die Fläche, auf der das Control liegt. Owner ist der Besitzer, der sich dann auch um die Freigabe kümmert. Wenn du eine Komponente mit ....Create(ScrollBox) erzeugst, sprich die Scrollbox als Owner dem Konstruktor übergibst, gehören sie der Scrollbox und eine manuelle Freigabe ist nicht erforderlich.

Ich mache das so:

Delphi-Quelltext
1:
2:
LabeledImage := TLabeledImage.Create(Self);  //oder müsste es TLabeledImage.Create(ScrollBox1) sein?
LabeledImage.Parent := ScrollBox1;

Also gehören sie damit der Scrollbox, eine manuelle Freigabe ist damit überflüssig? Sehe ich das richtig?

Edit:
Bzw. gehören sie mit Create(Self) dem Formular und eine manuelle Freigabe ist ebenfalls nicht erforderlich? Oder?


Gausi - Mo 12.10.20 20:03

Wenn die beiden Zeilen innerhalb einer Methode der Form stehen, und sich das self somit auf eine TForm bezieht, dann wird das LabeledImage beim freigeben der Form auch freigegeben.

Du muss also nichts weiter tun.

TLabeledImage.Create(ScrollBox1) wäre ggf. sinnvoller, wenn auch die Scrollbox dynamisch erstellt wird und im Verlauf des Programms freigegeben soll - inklusiver aller Komponenten in der Scrollbox. Aber wenn beides bis zum Ende des Programms bleiben soll, dann ist es relativ egal, wer der Owner ist.


galagher - Mo 12.10.20 20:16

user profile iconGausi hat folgendes geschrieben Zum zitierten Posting springen:
Wenn die beiden Zeilen innerhalb einer Methode der Form stehen, und sich das self somit auf eine TForm bezieht, dann wird das LabeledImage beim freigeben der Form auch freigegeben.
Ja, sie stehen in procedure TForm1.CreateLabeledImages([...]);

user profile iconGausi hat folgendes geschrieben Zum zitierten Posting springen:
TLabeledImage.Create(ScrollBox1) wäre ggf. sinnvoller, wenn auch die Scrollbox dynamisch erstellt wird und im Verlauf des Programms freigegeben soll - inklusiver aller Komponenten in der Scrollbox. Aber wenn beides bis zum Ende des Programms bleiben soll, dann ist es relativ egal, wer der Owner ist.
Ich muss zur Laufzeit nur die TLabeledImage's freigeben, weil sie beim Einlesen einer Datei jeweils neu erzeugt werden müssen. Klappt auch problemlos. Die ScrollBox bleibt während der gesamtem Laufzeit des Programms bestehen.
Wenn ich TLabeledImage.Create(ScrollBox1) angebe, führt dies sofort zu einem Fehler:
Zitat:
Komponente mit der Bezeichnung LabeledImage0 existiert bereits.

Oder, an anderer Stelle:
Zitat:
Zugriffsverletzung bei Adresse 0069A6FC in Modul 'FotoSort.exe'. Lesen von Adresse 000001C8.


Also belasse ich es bei TLabeledImage.Create(Self) und LabeledImage.Parent := ScrollBox1 (Self ist TForm1) und gut?


jaenicke - Mo 23.11.20 15:32

user profile icongalagher hat folgendes geschrieben Zum zitierten Posting springen:
Zitat:
Komponente mit der Bezeichnung LabeledImage0 existiert bereits.
Wir vergeben schlicht auch einen Namen für die erstellten Komponenten um den Fehler zu vermeiden. Bei uns werden aber auch Teile der Komponenten wieder zwischendurch entfernt, so dass wir den korrekten Owner haben möchten.