![]() |
Unterschied zwischen nil, FreeAndNil und Free in TForm
In einer legacy Applikation habe ich an ganz vielen Orte
Delphi-Quellcode:
gesehen im
Form1 := nil
Delphi-Quellcode:
(
OnClose
Delphi-Quellcode:
), anstellen von
Form1.FormClose
Delphi-Quellcode:
.
Action := ca.Free
Was ist der Unterschied wenn ich in
Delphi-Quellcode:
FormClose
aufrufe? |
AW: Unterschied zwischen nil, FreeAndNil und Free in TForm
In der alten Application (alte Delphiversion) gabs eventuell die Action noch nicht.
Grundsätzlich sollte ein .Free ja reichen. nil setzen manche, weil sie zur Laufzeit auf nil abfragen wollen...um zu vermeiden, ein fregegebenes oder noch nciht erzeugtes Objekt zu benutzen. Aber vom Prinzip her reicht Free vollkommen aus. Sherlock |
AW: Unterschied zwischen nil, FreeAndNil und Free in TForm
Zitat:
Das 2. setzt nur die Vraible auf Nil, ohne die Instant freizugeben, diese existiert weiterhin. Das 3. gibt die Instanz freu und setzt die Referenzvariable zurück. |
AW: Unterschied zwischen nil, FreeAndNil und Free in TForm
Der Unterschied ist, dass in
![]()
Immer unter dem Gesichtspunkt, dass die Form-Instanz auch wirklich freigegeben werden soll. Und in der Variablen
Delphi-Quellcode:
ist ja auch nicht gesichert die Instanz-Referenz zur aktuellen Instanz drin ;)
Form1
|
AW: Unterschied zwischen nil, FreeAndNil und Free in TForm
SUPER! Vielen Dank :-) :thumb:
|
AW: Unterschied zwischen nil, FreeAndNil und Free in TForm
Vielleicht noch ein Beispiel:
Delphi-Quellcode:
Hier gibt es u. U. keine Fehlermeldung, obwohl das Objekt freigegeben wurde, bzw. es wurde nur das Objekt freigegeben, ohne jedoch die Adresse zu löschen. U.U. hat sl also noch die alte Adresse und die zeigt ins Nichts und das Programm funktioniert mit Fehler, liefert also falsche Daten.
var
sl: TStringList; begin sl := TStringList.Create; sl.Add('Hallo'); ShowMessage(IntToStr(sl.Count)); sl.Free; ShowMessage(IntToStr(sl.Count)); end;
Delphi-Quellcode:
Hier wird auch die Adresse von sl gelöscht, genilt, bzw. auf 0 gesetzt. Hier gibt es eine Fehlermeldung.
var
sl: TStringList; begin sl := TStringList.Create; sl.Add('Hallo'); ShowMessage(IntToStr(sl.Count)); FreeAndNil(sl); ShowMessage(IntToStr(sl.Count)); end; |
AW: Unterschied zwischen nil, FreeAndNil und Free in TForm
Delphi-Quellcode:
macht garnichts, außer die Variable auf nil zu setzen ... die Form interessiert das aber sowas von garnicht.
Form1 := nil
Wofür es aber hilft, wenn man irgendwo noch auf Form1 zugreift, nachdem die Form schon freigegeben wurde ... dann bekommt man verständlichere Exceptions mit "Zugriffsverletzung bei Adresse 0". |
AW: Unterschied zwischen nil, FreeAndNil und Free in TForm
Zitat:
Zitat:
Also "ungeschickt", "meistens falsch" oder "macht gar nichts" ist vielleicht ein wenig unüberlegt. Wäre natürlich auch denkbar, das der ursprüngliche Programmierer wirklich keinen blassen Schimmer hatte. |
AW: Unterschied zwischen nil, FreeAndNil und Free in TForm
Das Benutzen der globalen Variablen für die Forms ist unüberlegt.
Das Benutzen der globalen Variablen für diese Formklasse gleicht einem Schuss ins eigene Knie. |
AW: Unterschied zwischen nil, FreeAndNil und Free in TForm
Zitat:
Interessant, was sich hier so tummelt. |
AW: Unterschied zwischen nil, FreeAndNil und Free in TForm
Im Prinzip wurden diese Variablen wohl nur angelegt, damit man die anderen Forms erreichen konnte, wenn man alle Forms automatisch erstellen lässt.
Aber am Liebsten würde ich die auch abschaffen oder zumindestens anders implementieren wollen. |
AW: Unterschied zwischen nil, FreeAndNil und Free in TForm
Zitat:
Mit dieser Variablen zu arbeiten ist deshalb unüberlegt, weil man sich damit verwehrt, mal mehr als eine Instanz eines solchen Forms zu haben (das soll in der Tat vorkommen). |
AW: Unterschied zwischen nil, FreeAndNil und Free in TForm
Moment. Bevor Ihr Euch weiter über die Vewendung globaler Variablen auslasst, lest zuvor bitte alle (!) existierenden Threads zu diesem Thema. Wenn Ihr danach dann noch etwas substantiell Neues beizutragen habt, dann gern her damit.
|
AW: Unterschied zwischen nil, FreeAndNil und Free in TForm
Ich wollte keine Diskussion über Sinn und Unsinn globaler Variablen anzetteln, sondern die korrekte Beantwortung einer Frage in den Mittelpunkt stellen: Eine Frage nach dem Unterschied zwischen drei Codezeilen sollte man mit der Erklärung des Unterschiedes der drei Codezeilen beantworten und nicht mit einem "Alles Käse". Zumindest war das mein Eindruck der Antworten.
Zitat:
Ach, und das es 'falsch' ist, kann auch nicht stimmen: Etwas 'falsches' funktioniert i.A. nicht (Das ist mein Verständnis von 'falsch'). Es ist einfach nicht state-of-the-art, ebenso wie ein Verbrennungsmotor, Plastiktüten oder Schnurrbärte (oder sind die wieder In?); Trotzdem lebt man damit. Man fährt auf lange Sicht nicht gut mit diesen Dingen, denn sie sind nicht nachhaltig, beinhalten Stolperfallen, machen einem das Leben schwer usw. Wobei Schnurrbärte auch bald wieder in Mode sein werden. |
AW: Unterschied zwischen nil, FreeAndNil und Free in TForm
Zitat:
Kannst du ein konkretes Beispiel mit dem Unterschied zwischen "globalen Variablen für die Forms" und "globalen Variablen für diese Formklasse". Und natürlich noch ein drittes Beispiel, wo aufzeigt wie du ein Form/eine Formklasse behandelst :) Danke :thumb: |
AW: Unterschied zwischen nil, FreeAndNil und Free in TForm
Delphi-Quellcode:
Wenn man basierend auf dem RAD Ansatz programmiert ist daran erst einmal nichts auszusetzen, leider verstehen die wenigsten diesen Ansatz, brechen die Vereinbarungen (auf die man sich mit RAD einlässt) und wundern sich warum das nicht funktioniert.
type
TForm1 = class( TForm ) Edit1 : TEdit; procedure Foo; end; var Form1 : TForm1; implementation uses Form2Unit; procedure TForm1.Foo; begin // globale Variable für die Forms Form2.Show; // globale Variable für diese Formklasse Form1.Edit1.Text := 'Foo'; // Bezug auf die Instanz, die in der Variablen Form1 hinterlegt ist // wenn schon, dann Self.Edit1.Text := 'Foo'; // Bezug auf die eigene Instanz // oder einfach Edit1.Text := 'Foo'; // Bezug auf die eigene Instanz end; RAD-Vereinbarungen:
|
AW: Unterschied zwischen nil, FreeAndNil und Free in TForm
Zitat:
Sichtbar war dabei die erste Instanz, aber in der Variable stand die zweite Instanz, weil die ja zuletzt die Variable überschrieb. Der Benutzer schrieb also was in Instanz 1, aber via Form1-Variable war das Geschriebene ntürlich nicht vorhanden. Oder man erstellt die Form mal dynamisch, weist aber nix der globalen Variable zu, sondern nutzt z.B. nur eine lokale Variable, oder gar blos ein WITH, weil die Form nur innerhalb einer Ereignismethode "kurz" verwendet und dann die Form sofort wieder freigegeben wird. |
AW: Unterschied zwischen nil, FreeAndNil und Free in TForm
Um ehrlich zu sein bin ich seit Tagen etwas verwirrt, weil ich nicht wirklich weiß ob ich das Problem verstehe. Geht es bei den globalen Form-Variablen um Grundlagen-Fragen, so dass ich die Frage nur an der falschen Stelle, also zu hoch ansetzte? Oder geht es hier um höhere Programmierung, ich also das Spezielle nicht erkenne?
|
AW: Unterschied zwischen nil, FreeAndNil und Free in TForm
Wenn es sich um eine RAD-Anwendung handelt, dann ist die Verwendung der globalen Form-Variablen erlaubt (gehören ja zum Konzept), aber nur lesend und die Instanzen müssen tabu sein (gehört ebenfalls zum Konzept).
Die Ausgangsfrage: Zitat:
In einer nicht RAD-Anwendung ist der erste Punkt erlaubt aber die anderen beiden Punkte sind falsch, denn dort sind die globalen Form-Variablen absolut tabu (am besten werden die sofort gelöscht). Es gibt auch noch so einen Mischmasch aus RAD und nicht RAD, den würde ich aber dringend empfehlen zu eliminieren. Also nur das Haupt-Formular (auch zu finden auch unter
Delphi-Quellcode:
) wird zum Anwendungsstart erzeugt, alle anderen dynamisch.
Application.MainForm
|
AW: Unterschied zwischen nil, FreeAndNil und Free in TForm
Danke für die super und sehr ausführliche Erklärung Sir Rufo :thumb: :-D
|
AW: Unterschied zwischen nil, FreeAndNil und Free in TForm
Ich würde, nur weil ich meine Forms nicht über
Delphi-Quellcode:
erstellen lasse (denn das ist es im Kern, worin sich das von Sir Rufo beschriebe unterscheidet), keineswegs von nicht RAD sprechen.
Application.CreateForm
![]() |
AW: Unterschied zwischen nil, FreeAndNil und Free in TForm
Zitat:
|
AW: Unterschied zwischen nil, FreeAndNil und Free in TForm
Ich entwickle seit Delphi 2 sehr schnell funktionierende Anwendungen. Ich nenne das 'Rapid Application Development'. Mehr ist das doch nicht. Aber auch nicht weniger, denn das ist das Gute an Delphi, aber auch an -z.B. Visual FoxPro.
RAD ist imho kein Paradigma, sondern ein Resultat eines so konzipierten Frameworks und der IDE. Der Ansatz von Visual FoxPro ist z.B. ein komplett anderer, trotzdem entwickelt man Programme in kürzester Zeit. Das mal zum Thema RAD oder nicht RAD (APP). Nähkästchen: Wenn ich das 30.ste Formular erstelle und beim starten merke, das dieser nun 10 Sekunden dauert, dann denke ich darüber nach, was ich hier so treibe und räume auf. Nun ja. Eigentlich fang ich erst gar nicht an, diesen Mist zu machen, denn jede Form bekommt eine Klassenmethode zum erzeugen und anzeigen.
Delphi-Quellcode:
Ach bitte: Keine Kommentare wegen dem bösen 'With'. Take it or leave it. I take it because I know what I'm doing.
Type
TForm1 = Class (TForm) ... class function Show (data :TSomeData) : Boolean; end; implementation class function TForm1.Show (data : TSomeData) : Boolean; Begin With TForm1.Create(nil) do begin InitData(data); Result := ShowModal = mrOK; if Result then WriteBackData(data); Release; end end; Die Routinen sehen natürlich nicht alle 100% identisch aus, aber im Prinzip sorge ich dafür, das ich mit einem Aufruf das Formular anzeige und das bisserl Logik dort verankere. Ich komme dabei zu 99% komplett ohne irgendwelche Bindings aus. Und, und darauf wollte ich hinaus: Ich komme komplett ohne Formularvariablen aus. Damit kann ich dann sehr einfach in einem Buttonclick ein Kindformular öffnen, womit wieder 99% der Anwendungsfälle abgedeckt sind. Die restlichen 1% (nicht modale Fenster, Threads und Statusaktualisierungen) erschlage ich mit Messages oder was mir sonst noch so einfällt. Und hier kommen dann globale Variablen ins Spiel. Ob ich diese globalen Variablen hinter einem Controller oder Container verberge, ist ja wurscht. 'Form1' ist für alle sichtbar, aber eben nur lesend. Da handle ich nach der Maxime: Wer Dreck macht, muss aufräumen, bzw. wer Form1 instantiiert, ist dafür verantwortlich, es auf den Müll zu schmeißen. So ein Container ist hier eine gute Sache, denn über den kann jeder Thread eine bitte zur Aktualisierung seines Status an das Formular schicken. Der Container entscheidet bzw. implementiert die Technik, wie die Form das mitbekommt, so bin ich von Synchronize und Queue unabhängig. Die Produktivität ist enorm, RAD at its best. Nicht weil ich so toll bin, sondern weil dieses Schrottdelphi (D7, XE) es mir wirklich leicht macht. Der Preis? Bei wachsender Komplexität wird die Anwendung sehr schnell nicht mehr leicht wartbar. Mit wachsender Komplexität ist aber nicht die Anzahl der Formulare gemeint, sondern die Businesslogik. Insofern würde ich bei großen Projekten auf RAD pfeifen, denn unterm Strich bin ich damit nicht schneller, eher im Gegenteil. Wenn ich aber auf irgend ein Riesenformular den 1000 Menüpunkt unterbringen soll, der noch ein Fenster aufmacht (Herr, schmeiss Hirn vom Himmel), dann mache ich genauso weiter (RAD, klick, bunt) , denn komplexer wird die Applikation dadurch ja nicht. Nur noch schlechter bedienbar. Abschließend will ich noch etwas loswerden: Ich bin froh, das man hier doch sehr hochwertige Beiträge findet. Die Aktivität der letzten Tage deuteten eher auf ein ziemlich eingeschlafenes Forum hin. :thumb: |
AW: Unterschied zwischen nil, FreeAndNil und Free in TForm
[OT]
Wir kommen etwas vom Thema ab, aber ich würde an der Stelle gern mal auf diesen Thread verweisen: ![]() Vielleicht kannst Du ja mal ein kleines Demoprojekt bauen und/oder ein kleines Video aufnehmen, mit dem man Deine Arbeitsweise live nachvollziehen kann. Mich würde das interessieren, da ich eigentlich eher den gegenteiligen Ansatz anstrebe - wenn ich Deinen Beitrag richtig interpretiere. Ich finde Bindings gerade sehr erstrebenswert, wenn sie gut umgesetzt sind (also nicht die von Emba). [/OT] |
AW: Unterschied zwischen nil, FreeAndNil und Free in TForm
Delphi-Quellcode:
von außerhalb. (niemals im eigenen OnClose oder Dergleichen)
Form1.Free;
Form1 := nil; // oder FreeAndNil(Form1); Wobei FreeAndNil ein "Schutz" ist, denn eigentlich macht es "NilAndFree", damit selbst bei einer Exception im Destructor die Variable definitiv immer auf NIL steht.
Delphi-Quellcode:
"irgendwas" auf NIL zu setzen ist jedenfalls nicht die gute Art,
// im OnClose
Action := caFree; if Form1 = Self then Form1 := nil; // das vielleicht ach erst im OnDestroy denn ist die z.B. Form mehrfach geladen, wenn würde man vielleicht den "falschen" Instanz-Zeiger aus der Variable löschen. Beispiel: Die Form wird via Form1.Release; freigegeben, also nicht jetzt, sondern später. in der Zwischenzeit wird die Form erneut angezeigt (neue Instanz), bevor die VCL zum verarbeiten der Message kam, also die alte Instanz wird erst freigegeben, wenn die Neue schon da ist und in der Variable steht womöglich schon der neue Instanz-Zeiger. [EDIT] Nicht "vielleicht", sondern "definitiv", denn bei einem direkten .Free wird OnClose garnicht aufgerufen. [INFO] Ich weiß, is bissl spät, aber wenn Andere das grade lesen, dann vielleicht doch nochmal bissl was genauer beschrieben. |
AW: Unterschied zwischen nil, FreeAndNil und Free in TForm
Zitat:
Ich glaube auch, dass es bisher keine IDE Einstellung "Forms nie automatisch erzeugen" gibt. Das fände ich praktisch, sollte aber natürlich nicht beim Anlegen des Hauptformulars eines neuen Projektes greifen... |
AW: Unterschied zwischen nil, FreeAndNil und Free in TForm
Zitat:
|
AW: Unterschied zwischen nil, FreeAndNil und Free in TForm
Sorry, stimmt ... das böse MainForm.
Hatte "Form1" nur genommen, weil es hier überall stand. :angle2: Ein neues Projekt ist eine Codevorlage. Da würde diese Aktion eh nicht greifen, da nicht wirklich eine FormUnit hinugefügt wird. |
AW: Unterschied zwischen nil, FreeAndNil und Free in TForm
Zitat:
Unter Tools/Optionen/Benutzeroberfläche/Formular-Designer/Autom. Formulare & Datenmodule |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:10 Uhr. |
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