Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Problem mit Tform und free (https://www.delphipraxis.net/155546-problem-mit-tform-und-free.html)

R2009 28. Okt 2010 05:52

Problem mit Tform und free
 
Hi DP'ler,

ich habe ein Problem mit dem dynamischen erzeugen und zerstören einer Form.

Delphi-Quellcode:
 If form_adressing=nil then
   begin
     Application.CreateForm(Tform_adressing, form_adressing);
   end;
  form_adressing.showmodal;
  form_adressing.destroy;
  form_adressing.free;
Rufe ich diesen Code zum ersten mal auf geht alles gut alles funktioniert. Rufe ich ihn zum zweiten Mal auf so erscheint eine Meldung: Object freed. Dies geschieht obwohl er die create Methode durchlaufen hat.
Die Form ist unter Delphi erstellt und.

Grüsse
Rainer

hoika 28. Okt 2010 06:08

AW: Problem mit Tform und free
 
Hallo,

Delphi-Quellcode:
var
  Form: TForm_Adressing; // lokale Variable
begin
  Form:= TForm_Adressing.Create(NIL);
  try
    Form.ShowModal;
  finally
    FreeAndNIL(Form);
   // oder
   // Form.Free; Form:= NIL;
  end;
Das von Delphi automatisch als globale Variable erstellte form_adressing
läßt du gleich ganz liegen.


Heiko

himitsu 28. Okt 2010 07:09

AW: Problem mit Tform und free
 
Delphi-Quellcode:
var Form: TForm_Adressing; // lokale Variable

Form := TForm_Adressing.Create(NIL);
try
  Form.ShowModal;
finally
  Form.Free;
end;
FreeAndNil ist hier eigentlich nicht nötig

Delphi-Quellcode:
with TForm_Adressing.Create(NIL) do
  try
    ShowModal;
  finally
    Free;
  end;

R2009 28. Okt 2010 07:09

AW: Problem mit Tform und free
 
Hi Hoika,

danke für deine Hilfe.
Freeandnil hat das Problem gelöst. Mir ist zwar nicht klar warum aber es funktioniert.
Destroy ist der destructor von Tform.
Wenn ich form.destroy und form:=nil aufrufe müsste das doch eigentlich genauso funktionieren wie bei Freeandnil.

Danke
Rainer

hoika 28. Okt 2010 07:16

AW: Problem mit Tform und free
 
Hallo,

Destroy ruft man nie selber auf, wenn dann Free.
Ich habe das FreeAndNIL genommen, weil du vorher noch auf <>NIL geprüft hattest,
das Free hätte hier aber gereicht.

Bei

Delphi-Quellcode:
Form.Free;
Form:= NIL;
würde vielleicht sogar der Compiler einen Hinweis bringen,
dass das Form:= NIL sinnloser Code ist.


Heiko

knochen 28. Okt 2010 07:24

AW: Problem mit Tform und free
 
Auszug aus der Delphi Hilfe:

Jede Ereignisbehandlungsroutine für das Formular oder für dessen untergeordnete Objekte sollte Release anstelle von Free [...] benutzen.

Die Gründe dafür stehen in der Hilfe.

Bezogen auf den Code des Fragestellers würde das für den Code heißen:

Delphi-Quellcode:
if form_adressing = nil then
begin
  Application.CreateForm(Tform_adressing, form_adressing);
end;
form_adressing.ShowModal;
form_adressing.Release;
form_adressing := nil;

nachti1505 28. Okt 2010 07:43

AW: Problem mit Tform und free
 
Zitat:

Zitat von knochen (Beitrag 1058281)
Auszug aus der Delphi Hilfe:

Jede Ereignisbehandlungsroutine für das Formular oder für dessen untergeordnete Objekte sollte Release anstelle von Free [...] benutzen.

Delphi-Quellcode:
if form_adressing = nil then
begin
  Application.CreateForm(Tform_adressing, form_adressing);
end;
form_adressing.ShowModal;
form_adressing.Release;
form_adressing := nil;

Ich kenne jetzt den Code drumherum nicht, aber befindet der Code sich an dieser Stelle in einer Ereignisbehandlungsroutine der Form???

Bernhard Geyer 28. Okt 2010 08:16

AW: Problem mit Tform und free
 
Zitat:

Zitat von knochen (Beitrag 1058281)
Jede Ereignisbehandlungsroutine für das Formular oder für dessen untergeordnete Objekte sollte Release anstelle von Free [...] benutzen.

Die Gründe dafür stehen in der Hilfe.

Bei Verwendung von ShowModal zum Anzeigen sorgt schon der Code in ShowModal dafür das kein Problem auftritt. Bei Verwendung von Show für einen nicht Modalen Dialog ist Release angebracht.

sx2008 28. Okt 2010 08:28

AW: Problem mit Tform und free
 
Wir hätten also 4 Wege um ein Formular freizugeben:
1.) Destroy
2.) Free
3.) FreeAndNil
4.) Release
Was soll man jetzt nehmen?

Destroy darf man nur aufrufen, wenn man 1000% sicher ist, dass das Objekt exisitiert:
Delphi-Quellcode:
var Form: TForm_Adressing; // lokale Variable
begin
  Form := TForm_Adressing.Create(NIL);
  try
    Form.ShowModal;
  finally
    Form.Destroy; // erlaubt, da garantiert ist dass "Form" <> nil
  end;
Mit Destroy kann man einige CPU-Zyklen sparen; allerdings sollte man doch besser Free verwenden.
Wir streichen also Destroy aus unserem Spielraum und merken uns dass man Destroy theoretisch verwenden kann.

FreeAndNil macht dann Sinn, wenn die Objektvariable nicht lokal, sondern global ist und ausserdem an anderen Stellen im Sourcecode mit Assigned abgeprüft wird.

Lokale Objekte werden immer mit Free freigegeben.
Dies gilt auch für globale Formularobjekte, wenn man sicher ist, dass nirgends mehr
auf diese Variable zugegriffen wird.

Release ist wiederum eine ganz spezielle Methode.
Wenn man z.B. mitten im OnClick-Event eines Formulars ist und Free aufrufen würde,
dann würde man sich das Objekt unterm Hintern weglöschen.
Mit der Folge einer Zugriffsverletzung.
Release schickt eine Windows-Message an das eigene Formular.
Diese Message wird erst empfangen und verarbeitet, wenn das Formular alle anderen
Messages verarbeitet hat.

Wir halten fest:
Destroy - Finger weg
Free - die Standardmethode
FreeAndNil - sparsam einsetzen; nur dort wo es Sinn macht
Release - nur verwenden, wenn das Formular sich selbst aus einem Event heraus freigeben möchte

blauweiss 28. Okt 2010 11:28

AW: Problem mit Tform und free
 
Hallo sx2008,

klasse Beitrag von Dir, sowohl inhaltlich als auch vom Aufbau. Danke ! :thumb:

Grüße,
blauweiss


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:22 Uhr.
Seite 1 von 2  1 2      

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