2012-04-12 66 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