我是否需要释放动态创建的表单?

时间:2014-11-13 21:52:45

标签: delphi memory-management

如果我使用TForm.CreateNew(Application)动态创建TForm来创建一个自由浮动窗口,我是否必须跟踪这些对象并在应用程序关闭时释放它们?

或者delphi会自动释放应用程序上的所有表单吗?

此外,如果我有一个自由浮动的动态创建表单并且用户点击关闭按钮会发生什么?我是否需要在某处调用某些代码来解放这些代码? 如果是这样,怎么样?我认为我无法将其置于任何形式的事件中。

4 个答案:

答案 0 :(得分:4)

只是触及其他答案未涵盖的重点......

是的,当您与所有者创建表单(或任何其他组件)时,将在销毁所有者时销毁该表单。 但是,非常NB: 这并不意味着您不会有泄漏。澄清:

  • 如果您每次创建表单时都将Application设置为所有者,那么当您的应用关闭时,表单将被Application对象销毁。
  • 但是(除非您编写额外的代码),当应用程序关闭时,这些表单将被销毁。
  • 换句话说,如果用户每次选择特定菜单项时都会创建应用程序拥有的特定表单,那么随着时间的推移会消耗更多内存。根据每次创建表单时使用的内存量,应用程序可能会耗尽内存。

因此,如果您不再重新创建对象,那么该模型是完全可以接受的。但是,这意味着您确实想要跟踪这些对象。但不是这样你可以自己释放它们,而是让你重新Show它们而不是重新创造它们。


还要涵盖问题中的其他一些要点:

  

如果我有一个自由浮动的动态创建表单窗口并且用户点击关闭按钮会发生什么?我是否需要在某个地方调用某些代码来释放它们?

如果您的用户下次显示您重复使用现有实例的表单,则不需要释放它们。如果您要创建新实例,则应在表单关闭时释放该表单。否则,只有当您的应用程序关闭时,所有旧实例才会被销毁。

  

如何?我认为我无法将其置于任何形式的事件中。

恰好Delphi提供了一个理想的事件:OnClose。如果挂钩该事件,则可以设置var Action: TCloseAction以指示表单关闭时应该发生的情况。默认情况下:

  • MDI表单将被最小化(caMinimize)。
  • 将隐藏SDI表单(caHide)。

您可以更改此选项以销毁表单(caFree)。

注意:如果您决定销毁该表单,请小心不要在销毁之后重新使用它。您指向表单的任何变量都将指向内存中的相同位置,但表单不再存在。

答案 1 :(得分:2)

您传递给CreateNew的参数是组件的所有者。当组件的所有者被销毁时,它会销毁它拥有的所有组件。因此,应用程序对象是表单的所有者。应用程序关闭时,应用程序对象将被销毁。因此它摧毁了所有自有组件。包括您动态创建的表单。

答案 2 :(得分:2)

  

我是否需要释放动态创建的表单?

不,除非您使用TForm.CreateNew(nil)创建表单,否则不会将所有者传递给构造函数。

CreateNew的参数是所有者,如果所有者(Application / Form / WhatEverYouLike)被删除,则将释放所有拥有的对象。试一试。

procedure TMainfom.Button1Click(Sender: TObject);
var
 a:TForm;
begin
 With Tform.CreateNew(Application) do
   begin
   OnClose := MyAllFormClose;
   OnDestroy := AllMyFormDestroy;
   Show;
   end;
end;

procedure TMainfom.AllMyFormDestroy(Sender: TObject);
begin
   Showmessage(':( I''m going to be destroyed')
end;

procedure TMainfom.MyAllFormClose(Sender: TObject; var Action: TCloseAction);
begin
  // unremark if you want to get the form freed OnClose already 
  // Action := caFree;    
end;

答案 3 :(得分:2)

我不知道为什么人们似乎认为形式是某种具有自己独特行为和规则的神奇实体。

表单是从TForm和TCustomForm派生的常规对象,它们最终派生自TObject,就像Delphi中的每个其他类一样。

如果您动态创建从TObject派生的任何内容,它将在应用程序终止时被销毁。但是,如果您未能自行销毁它并将其留给系统,那通常被认为是“内存泄漏”。对于运行一次并快速终止的程序来说,这不是什么大问题。但是对于用户将持续数小时或数天打开的东西,内存泄漏可能会变得非常烦人。

如前所述,TForms有一个OnClose事件,它有一个参数Action。您可以将Action设置为caFree,并在返回显示它的Show或ShowModal调用时销毁该表单。但是如果你使用它,你需要自己创建表单对象,而不是使用默认的自动创建机制。

其他类型的对象没有这个,比如TStringList。你只需要练习"安全对象管理"并确保创建的对象也及时被销毁,包括表单。这可以进入一个关于垃圾收集,接口和大量相关内容的讨论的整个老鼠的巢。可以这么说,你需要了解选项并适当地管理你的对象生命周期,而不是让它们在应用程序终止时被销毁。