2009-05-27 35 views
9

Delphi在線幫助表示應該使用Release從內存中刪除表單。然而,在模式窗體很多例子我已經看到了這個結構:在Delphi中使用Free而不是Release可以安全使用模式形式嗎?

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

可以自由破壞模式窗體一個安全的方式?正如我在ShowModal的源代碼中所見,Application.HandleMessage將被調用,直到ModalResult不爲0。這就是Free爲什麼不能干擾未決的Windows消息的原因嗎?

+0

相關:http://stackoverflow.com/questions/274523/form-release-nil – mjn 2011-12-19 07:21:09

回答

14

是的,在撥打ShowModal後可以安全使用Free

您需要使用Release的情況是您處於事件處理程序中間的時間(例如,OnClick),事件之後的進一步處理必須訪問該表單。在這種情況下,調用Release而不是發佈CM_RELEASE消息,該消息不釋放事件,直到事件處理程序完成並且控制已返回到消息泵(ProcessMessages/Application.Run)。 ShowModal不會返回,直到事件處理程序完成並且控件使其備份堆棧,因此之後調用Free實際上是相同的地方,否則將處理CM_RELEASE消息。

3

當然,你也可以使用FreeAndNil例程。 FreeAndNil例程只會釋放該對象,如果它尚未爲零,並且在釋放之後也將其設置爲零。如果直接在已釋放的對象上調用免費,則會出現訪問衝突。

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

小nitpick:自由也將只釋放對象,如果它不是已經零,第二部分是重要的。 – mghie 2009-05-27 17:16:36

+3

如果MyForm是一個局部變量,使用FreeAndNil()肯定是矯枉過正。 MyForm.Free就足夠了,實際上MyForm.Destroy也可以工作。 – 2009-05-27 17:49:54

+1

+對於Allen - FreeAndNil的過度使用可以隱藏編譯器可能拾取的錯誤 - 如果對象可能沒有被初始化(通常爲條件創建),它不會抱怨。 這也不回答問題(YES IT IS OK)。 – 2009-05-27 23:32:29

4

這取決於。 Free表單不調用Release所做的事件處理程序,並且可能已發佈到表單並排隊的任何消息都不會被處理。因此,在許多情況下(大多數情況下,調用Free(或FreeAndNil))都可以正常工作,但由於看似隨意的原因,可能會導致一些非常奇怪的行爲。

,我會建議在OnClose事件設置的行動caFree,這樣的選擇:

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

然後你可以這樣寫代碼:

TMyForm.Create(nil).ShowModal; 

而你不知道不需要專門釋放表單,因爲它完成後會自行釋放。

相關問題