2012-04-12 62 views
0

我從來沒有注意到它在我的程序中,但對於我的TForm之一,我有一個銷燬事件,釋放一個對象,被多次調用或觸發。我不明白爲什麼。爲什麼形式摧毀事件被稱爲不止一次?

procedure THTrendFrm.FormDestroy(Sender: TObject); 
begin 
    LogAlarm.Free; <---Invalid Pointer Operation exception is raised 
end; 

由於提前,

更新:這是之後我的計劃是關閉FastMM消息窗口。 012larm.sh是創建LogAlarm的類。 enter image description here enter image description here

+0

您是否嘗試過我的建議?在Application.Run之後,從.dpr文件的表單對象中調用Free。 – 2012-04-13 06:43:52

+0

@DavidHeffernan我確實應用了你的建議,FastMM仍然發現了錯誤。 – ThN 2012-04-13 13:23:24

+1

我只是想出了我的問題。我剛剛在項目dpr文件中看到了兩次Application.CreateForm(THTrendFrm,HTrend)。我刪除了重複,它工作正常。 – ThN 2012-04-13 13:38:24

回答

1

感謝David Heffernan等人。我發現了我的問題並修復了它。有問題的TForm正在像我這樣在我的項目文件中創建兩次。

Application.CreateForm(HTrendFrm,HTrend);

這解釋了爲什麼摧毀被稱爲兩次。

一旦我刪除重複行,它正在關閉罰款。

2

TForm.OnDestroy事件不會多次調用,所以你必須要在其他地方釋放的LogAlarm對象在代碼觸發OnDestroy事件之前。

+0

我認爲有一個VCL錯誤,意味着形式可以銷燬兩次。我通過在.dpr文件中銷燬我的主窗體而不是讓應用程序通過所有者機制銷燬它來解決這個問題 – 2012-04-12 20:36:35

+0

Remy Remy,我確實在這一行放了一個break,並在關閉程序時加入。它在這條線上斷了兩次。第一次沒有異常或錯誤信息。第二次,它提出了例外。 LogAlarm對象在相同的Unit或Pas文件中創建和銷燬。它不會在我的項目文件中沒有釋放。 – ThN 2012-04-12 20:57:22

+2

@DavidHeffernan:我從來沒有遇到過這樣的bug。 – 2012-04-12 20:58:55

0

這取決於您如何創建LogAlarm。

如果LogAlarm是一個TComponent後代,並且您已經使用窗體作爲所有者創建它,則不應該對其調用Free,因爲組件將在表單被銷燬後​​自動清理。

或者如果您堅持自己清理它,請在創建過程中將所有者保留爲零。

+1

釋放所擁有的對象是完全安全的。你最後一句話是不正確的。釋放一個對象會將其從擁有者擁有的對象列表中移除。 – 2012-04-12 22:08:44

+0

這並不是我的意思。我的觀點是,如果你不希望業主進行清潔,你應該像創建(無)構造。在進行調試時,可能首先排除編程錯誤,然後再假定它是vcl中的一個錯誤。 – 2012-04-13 04:13:44

+0

我稍微改寫了最後一句 – 2012-04-13 04:16:24