2009-05-27 2 views
9

Die Delphi Online-Hilfe sagt, dass Release verwendet werden sollte, um ein Formular aus dem Speicher zu entfernen. Jedoch habe ich in vielen Beispielen für modale Formen dieses Konstrukt gesehen:Ist es sicher, für Modalformulare in Delphi Free statt Release zu verwenden?

MyForm := TMyForm.Create(nil); 
try 
    MyForm.ShowModal; 
finally 
    MyForm.Free; 
end; 

Ist Free eine sichere Möglichkeit, eine modale Form zu zerstören? Wie ich in der Quelle für ShowModal sehen kann, wird Application.HandleMessage aufgerufen, bis das ModalResult nicht 0 ist. Ist dies der Grund, warum Free nicht mit ausstehenden Windows-Nachrichten interferieren kann?

+0

In Verbindung stehende: http://stackoverflow.com/questions/274523/form-release-nil – mjn

Antwort

14

Ja, es ist sicher zu verwenden Free nach einem ShowModal Anruf.

Die Fälle, in denen Sie Release verwenden müssen, sind Zeiten, in denen Sie sich in der Mitte eines Ereignishandlers befinden (z. B. OnClick), wo die weitere Verarbeitung nach dem Ereignis auf das Formular zugreifen muss. In diesem Fall sendet der Aufruf Release stattdessen eine Nachricht CM_RELEASE, die das Ereignis nicht freigibt, bis der Ereignishandler beendet ist und die Steuerung an die Nachrichtenpumpe zurückgegeben wurde (ProcessMessages/Application.Run). ShowModal kehrt nicht zurück, bis der Event-Handler beendet ist und die Kontrolle den Stack sichern lässt. Daher ist der Aufruf von Free später derselbe Ort, an dem die Nachricht sonst verarbeitet würde.

+0

Und seien Sie vorsichtig, keine Application.ProcessMessages Aufrufe zu haben! –

+0

@GerryColl Warum? Und wo genau? – Bozzy

+0

@Bozzy Wenn Sie 'Release' verwenden und dann' Application.ProcessMessages' aufrufen, wird die 'WM_RELEASE' Nachricht verarbeitet und das Formular wird freigegeben. Gerrys Sorge ist, wenn Sie Release verwenden, um die Zerstörung zu verschieben und dann das Formular versehentlich zu löschen, bevor Sie damit fertig sind. –

3

Absolut, und Sie können auch die FreeAndNil-Routine verwenden. Die FreeAndNil-Routine wird das Objekt nur dann freigeben, wenn es noch nicht nil ist, und es auch nach dem free auf nil setzen. Wenn Sie direkt auf ein Objekt zugreifen, das bereits freigegeben wurde, erhalten Sie eine Zugriffsverletzung.

MyForm := TMyForm.Create(nil); 
try 
    MyForm.ShowModal; 
finally 
    FreeAndNil(MyForm); 
end; 
+4

Kleiner Nitpick: Free wird auch nur das Objekt befreien, wenn es nicht schon Null ist, ist der zweite Teil der wichtige. – mghie

+3

Wenn MyForm eine lokale Variable ist, ist die Verwendung von FreeAndNil() sicherlich übertrieben. MyForm.Free ist ausreichend, tatsächlich würde MyForm.Destroy genauso gut funktionieren. –

+1

+ für Allen - Die übermäßige Verwendung von FreeAndNil kann Fehler verstecken, die vom Compiler aufgefangen wurden - es wird sich nicht beschweren, wenn das Objekt möglicherweise nicht initialisiert wurde (normalerweise bedingte Erstellung). Dies beantwortet auch nicht die Frage (Ja, es ist OK). –

4

Kommt drauf an. Free Das Formular ruft nicht die Ereignishandler auf, die Release tut, und alle Nachrichten, die möglicherweise in das Formular gestellt und in die Warteschlange gestellt wurden, werden nicht verarbeitet. Während also in vielen und möglicherweise in den meisten Fällen der Aufruf Free (oder FreeAndNil) gut funktioniert, kann es aus scheinbar zufälligen Gründen zu einem höchst merkwürdigen Verhalten führen.

Die Alternative, die ich in der OnClose Ereignis würde vorschlagen, die Aktion zu caFree, wie diese ein:

procedure FormClose(Sender : TObject; Action : TCloseAction) 
begin 
    Action := caFree; 
end; 

können Sie dann Code wie folgt schreiben:

TMyForm.Create(nil).ShowModal; 

Und Sie don Sie müssen das Formular nicht extra freigeben, da es sich selbst befreit, wenn es fertig ist.

+0

Ich mag die Kreativität, die das zeigt, aber ich würde es nie verwenden, da der in der Frage gezeigte Code nur die idiomatische Art ist, es zu tun - mit deinem Code würde ich mich immer fragen, ob das Formular korrekt freigegeben wird, wenn ich nach einigen Monaten darüber stolpere . – mghie

+0

Meh, was immer du fühlst ist das Beste. Dies kapselt jedoch die Funktionalität des Formulars vollständig und reduziert Ihre Chance, es zu vergessen, es zu befreien. –

+0

Einstellung Aktion auf CaFree ruft einfach Release. Sie müssen vorsichtig sein, wenn Sie nach showmodal auf Eigenschaften des Formulars zugreifen möchten, falls etwas (defekt?) ProcessMessages aufruft –

Verwandte Themen