AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Welchen Sinn macht dieser Code?

Ein Thema von Popov · begonnen am 30. Aug 2014 · letzter Beitrag vom 30. Aug 2014
Antwort Antwort
Popov
(Gast)

n/a Beiträge
 
#1

Welchen Sinn macht dieser Code?

  Alt 30. Aug 2014, 13:27
Vielleicht liegt es daran, dass ich Formulare selten erst zur Laufzeit erzeuge oder weil ich noch nicht richtig wach bin, aber ich verstehe den tieferen Sinn des Beispiels nicht. Der ist vermutlich schon vorhanden.
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
  Form2 := TForm2.Create(Self);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Form2 := TForm2.Create(Application);
  Form2.ShowModal;
  Form2.Release;
end;
Form2 ist in Liste der verfügbaren Formulare. Zuerst stelle ich mir die Frage: warum? Wenn der Programmierer es sofort in Create von Form1 erzeugt, dann hätte man es auch direkt einbinden können. Um das Formular anzuzeigen braucht man nicht den Code in Button1Click, das würde auch so gehen. Einfach Form2.ShowModal.

Betrachten wir das anders, Form2 wird nur gelegentlich benötigt. Somit macht der Code in Button1Click Sinn, wozu dann aber der Part in FormCreate?

Und wenn wir schon dabei sind, wieso einmal TForm2.Create(Self) und einmal TForm2.Create(Application)?


//EDIT:

Was ich noch vergessen habe zu sagen: natürlich wird in FormCreate von Form2 etwas erledigt was für Form1 auch wichtig ist, aber kann es es sein dass der Programmierer einfach nur vergessen hat das Fenster danach wieder frei zu geben? Es also keinen tieferen Sinn macht?

Geändert von Popov (30. Aug 2014 um 13:36 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.115 Beiträge
 
Delphi 12 Athens
 
#2

AW: Welchen Sinn macht dieser Code?

  Alt 30. Aug 2014, 13:47
Die Sache mit dem Owner hast du aber verstanden?

Create(Self) besagt, daß hier Form1 der Owner ist und wenn Form1 freigegeben wird, dann wird dvon auch Form2 freigegeben.
Ich hoffe nur, daß hier die Variable Form2 auch eine Private der Form1 ist und nicht die Globale.

Und beim Anderen ist die Application der Owner, womit das freigegeben würde, wenn die Anwendng beendet wird.
Rein formal wäre es hier aber auch besser das Self zu übegeben, da die Form2 dort ja nur aktiv ist, solange es Form1 gibt, bzw. nur solange der Button-Klick ausgeführt wird.
Womit man das auch eigentlich nil lassen könnte, da die Form ja manuell freigegeben wird und sich "eigentlich" kein anderer um die Freigabe kümmern müsste.

Da man dort aber den Resourcenschutzblock vergessen hat, kümmert sich dann die Applikation um die Freigabe, wenn es im ShowModal knallt (Exception), was schnell passiert, wenn z.B. TForm2.Visible=True ist.
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  Form2: TForm2;
begin
  Form2 := TForm2.Create(Application); // Hier eigentlich besser Self, da eine Methode Dieses ja das Ding erstellt und freigibt. Oder nil, da es manuell freigegeben wird und kein Owner nötig ist.
  try
    Form2.ShowModal;
  finally
    Form2.Release; // Das ist fast sowas wie Form2.Free; nur daß beim Free die Form sofort freigegeben wird und beim Release erst später, wenn das Programm Lust dazu hat.
  end;
end;
Und auch da ist wieder der Schrott mir der globalen Variable, denn die Form wird hier nur lokal erstellt und gleich wieder freigegeben.


PS: Man kann eine Form mehrfach erstellen und gleichzeitig anzeigen.
Und gerade deswegen waren auch die bösen Kommentare zu der globalen Form2-Variable.

Im TForm1.FormCreate wird deas Fenster einmal erstellt und in Button2.Click nochmal.
Wenn man jetzt noch die automatische Erstellung im Projekt aktiv lässt, dann gibt es diese Form 2 bis 3 Mal.

Wenn jetzt noch die globale Variable Form2 für alles verwendet wird, dann rate mal welche Form darin verlinkt ist und auf was man zugreift, wenn man diese benutzt.
Tipp: Nach dem Buttonklick, steht da schrott drin, nämlich die veraltete Referenz auf die Form von dort, welche es nicht mehr gibt.


Und dann noch das TForm2.Visible:
Wenn das auf False steht dann wird die Instanz aus FormCreate nicht angezeigt, da dort das Show, bzw. Visible:=True fehlt.
Und wenn das True ist, dann wird die Instanz aus FormCreate angezeigt, aber der Aufruf im Button1Click schlägt fehlt, denn eine sichtbare Form kann nicht Modal werden,
weswegen auch der Hinweis auf den Resourcenschutzblock war, da dann die Form nicht mehr freigegeben wird. (Release wird ja nicht mehr ausgeführt)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (30. Aug 2014 um 13:58 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#3

AW: Welchen Sinn macht dieser Code?

  Alt 30. Aug 2014, 14:05
Eigentlich ist es ganz einfach was da passiert:
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
  // Erzeugen einer Instanz und die Referenz wird in Form2 gespeichert
  Form2 := TForm2.Create(Self);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  // Erzeugen einer Instanz und die Referenz wird in Form2 gespeichert
  Form2 := TForm2.Create(Application);
  Form2.ShowModal;
  Form2.Release;
end;
Nachdem dem Aufruf von TForm1.FormCreate haben wir also eine Instanz-Referenz in Form2 stehen.

Jetzt kommt der Aufruf von TForm1.Button1Click und es wird eine neue Instanz erzeugt, die Referenz in Form2 gespeichert und am Ende wird die Instanz freigegeben.

Jeder Zugriff auf die Instan, deren Referenz in Form2 steht, würde jetzt aber eine Zugriffsverletzung auslösen, denn diese Instanz wurde ja freigegeben.

Es dümpelt zwar irgendwo noch eine Instanz von TForm2 herum, aber wir haben ja - vorsorglich - die Referenz darauf vergessen (dann kann die auch nicht kaputt gehen)

Einen Memoryleak haben wir nicht, denn beim Beenden der Anwendung wird diese vergessene Instanz durch die Owner-Beziehung korrekt freigegeben.

Nein, Sinn macht das ganze nicht, es sei denn, man möchte einfach nur Speicher belegen.

EDIT:
Hier mal eine kleine Erweiterung
Delphi-Quellcode:
type
  TForm1 = class( TForm )
    Button1 : TButton;
    Button2 : TButton;
    procedure FormCreate( Sender : TObject );
    procedure Button1Click( Sender : TObject );
    procedure Button2Click( Sender : TObject );
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1 : TForm1;

implementation

{$R *.dfm}

uses
  Unit2;

procedure TForm1.Button1Click( Sender : TObject );
begin
  Form2 := TForm2.Create( Application );
  Form2.ShowModal;
  Form2.Release;
end;

procedure TForm1.Button2Click( Sender : TObject );
begin
  Form2.ShowModal;
end;

procedure TForm1.FormCreate( Sender : TObject );
begin
  Form2 := TForm2.Create( Self );
end;
Nach dem Start einfach mal auf den Button2 klicken und wunderbar, es funktioniert.
Jetzt auf Button1 (geht auch) und dann wieder auf Button2 -> Zugriffsverletzung (wie zu erwarten)

EDIT2:
Und korrekterweise sollte das dann so aussehen:
Delphi-Quellcode:
procedure TForm1.Button3Click( Sender : TObject );
var
  LForm : TForm2;
begin
  // wozu einen Owner, wenn wir es eh wieder freigeben wollen?
  // die Referenz in einer lokalen Variable speichern
  // try..finally um die Instanz gesichert wieder freizugeben
  LForm := TForm2.Create( nil );
  try
    LForm.ShowModal;
  finally
    LForm.Free;
  end;
end;
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (30. Aug 2014 um 14:16 Uhr)
  Mit Zitat antworten Zitat
Popov
(Gast)

n/a Beiträge
 
#4

AW: Welchen Sinn macht dieser Code?

  Alt 30. Aug 2014, 14:20
Die Sache mit dem Owner hast du aber verstanden?
Das eigentlich schon, nur hätte ich es nur anders gelöst. Was mich etwas verwirrt hat war, dass Form2 in FormCreate für einen Job erzeugt, dann aber nicht wieder freigegeben wird. Vor allem, weil es in Button1Click nach dem Job sofort immer freigegeben wird. Und dann weil Owner mal Self, mal Application ist. Ich dachte das hat einen speziellen Hintergrund.

Danke für die Erklärungen.
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.270 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: Welchen Sinn macht dieser Code?

  Alt 30. Aug 2014, 15:07
Hallo,

kurz und knapp.
Der Code macht keinen Sinn.

Heiko
Heiko

Geändert von hoika (30. Aug 2014 um 15:10 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.115 Beiträge
 
Delphi 12 Athens
 
#6

AW: Welchen Sinn macht dieser Code?

  Alt 30. Aug 2014, 15:54
Der Code macht keinen Sinn.
Wenn die Form wirklich einmal dauerhaft und dann nocheinmal kurz für jeden Button-Klick vorhanden sein soll, dann wäre es schon "sinnvoll".

Aber dann nicht auf der selben Variable und mit ein paar weiteren Änderungen.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Popov
(Gast)

n/a Beiträge
 
#7

AW: Welchen Sinn macht dieser Code?

  Alt 30. Aug 2014, 16:12
Ok, ich hab mir den Code jetzt weiter angesehen. In FormCreate von Form2 steht nur eine Zeile mit einer Prozedur. In der Prozedur werden einige Daten von Form1 an Form2 übergeben. Form2 ist ein Optionsfenster. Somit ergibt die Zeile Form2 := TForm2.Create(Self); in FormCreate von Form1 sowieso keinen Sinn.

Das Ganze macht erst Sinn in Button1Click, da da auch Informationen von Form2 an Form1 zurück fließen.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:03 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