2008-11-08 54 views
9

如果在使用表單之後調用Form.Release,它將釋放所有相關的內存,但不會將表單變量設置爲nil。Form.Release + NIL

if not assigned (Form1) then 
    begin 
    Application.CreateForm(Tform1, Form1); 
    try 
     // Do something 
    finally 
     Form1.Release 
    end; 
    end; 

爲了能夠再次調用相同的代碼,Form1中會有一些點被設置爲零。從發佈的說明我不能做

Form1 := nil; 

發佈之後,因爲釋放過程將被調用後和形式實際上是釋放之前直接返回。我無法檢測Form.Release何時完成將表單var設置爲nil。

這樣做的最好方法是什麼?

霍爾格

回答

14

放線

Form1 := nil; 

只是調用釋放後。

Release只是發佈一個CM_RELEASE消息給表單,它允許表單在處理CM_RELEASE消息之前完成其隊列中的事件(事件處理程序),這意味着通常只是調用Free。
所以,在調用Release之後,你不應該假設Form變量仍然指向一個有效的Form,因此將nil放入變量中。

0

在Delphi Win32的,免費的對象適當的方法是調用

FreeAndNil(Form1) 

這確實都工作在一個單一的電話。

不過,我有一種偷偷摸摸的感覺,你的問題比眼睛還要多。您是否在使用Delphi for .NET - 如果是,哪個版本?

+1

除了它不適用於您不使用免費但是發佈的表單... – 2008-11-08 08:58:20

+0

Roddy我使用的是Delphi Win32(對不起,不提)。據我瞭解,對於一個表單來說,執行更多的任務不僅僅是一個普通的FreeAndNil,它不會釋放表單擁有的組件。它是否正確? – Holgerwa 2008-11-08 09:24:42

11

發佈只是一個(可能)延期免費。在調用Release之後,你應該做的第一件事是修改變量。
然後,即使某些代碼試圖在實際銷燬之前引用Form1,也是安全的。在你的代碼中的情況下,它會安全地重新創建另一個Form1用於新的用法,而不會打擾被破壞的用戶。

2

如上所述釋放只是一個延期自由的表單使用,如果它想要關閉/自由本身。其他則被推遲,它與Release沒有什麼不同。所以在這個例子中調用Release沒有用處。免費呼叫似乎更合乎邏輯。調用Free或使用FreeAndNil後,您可以將其設置爲零。

如果你仍然想使用發佈,那很好。只需將變量值設置爲零即可。這樣做並不會使論壇的行爲有所不同。但請記住,在這種情況下,調用Free而不是Release更有效且更確定。我的首選是僅在真正需要的地方使用Release。

3

諸位可能只是始終調用這個:

procedure FreeOrReleaseAndNil(var Obj); 
var 
    Temp: TObject; 
begin 
    Temp := TObject(Obj); 
    Pointer(Obj) := nil; 
    if Temp is TCustomForm then 
    TCustomForm(Temp).Release 
    else 
    Temp.Free; 
end; 

確保澆注到TObject的,因爲你不能判斷obj的類型後檢查類型。這個應該是因爲像Free一樣是安全的,Release是非虛擬的。