为什么有些Delphi组件需要“AOwner:TComponent”来构建它们?

时间:2009-01-23 20:45:51

标签: delphi vcl

要求TComponent作为所有者来实例化某种对象似乎完全无关紧要。为什么有这么多需要这个的Delphi组件?

例如,TXMLDocument需要TComponent对象来实例化。

为什么会这样,如果有充分的理由,我应该在那里使用什么来“做正确的事”?

7 个答案:

答案 0 :(得分:35)

所有者组件应该管理其拥有的所有组件。当所有者被销毁时,拥有的组件会自动销毁。

这有助于开发人员只需从工具调色板中拖动组件,将其放在表单上,​​然后将事件挂钩以完成工作,而无需担心管理组件的生命周期。

表单是放在其上的所有组件的所有者。 Application对象是表单的所有者。当应用程序关闭时,Application对象将被销毁,从而销毁表单和所有组件。

但是创建组件时并不是必需的。如果将Nil传递给参数,则组件将在没有所有者的情况下创建,在这种情况下,您将负责管理组件的生命周期。

答案 1 :(得分:9)

所有TComponent后代都需要Owner,它在TComponent构造函数中定义。 Owner组件负责销毁所有Owned组件。

如果你想控制生命时间,你可以传递nil作为参数。

答案 2 :(得分:3)

只是添加一些额外的信息。

每个控件也有一个父级。 (一个TWinControl)。在所有者照顾生命的情况下,父母负责展示物品。

例如,表单有一个面板,面板有一个按钮。在这种情况下,表单拥有面板和按钮。但表单是面板的父级,面板是按钮的父级。

答案 3 :(得分:3)

还有其他一些需要注意的事项。我使用了多个第三方组件,依赖在构造函数Create中传递的所有者组件,如果传入Nil将抛出异常/ AV。

最终结果是,当您在IDE中以可视方式使用这些组件时,这些组件可以正常工作,但在运行时创建时会导致问题。

从某种意义上说,这些问题的原因是糟糕的设计。规则中没有任何内容表明您不能/不应该将NIL作为aOwner参数传递。

答案 4 :(得分:1)

对象不要求将tComponent作为AOwner传递。您可以轻松地将nil传递给此并自行处理破坏。大多数情况下,我倾向于将此技术用于本地化例程,其中正在使用的组件不会在当前方法之外使用。例如:

Procedure TForm1.Foo;
var
  XmlDoc : tXmlDocument;
begin
  XmlDoc := tXmlDocument.Create(nil);
  try
    // do processing of the XMLDoc here
  finally
    FreeAndNil(XmlDoc); 
  end;
end;

答案 5 :(得分:0)

你使用它有两个原因: - 所有权机制也是一种垃圾收集系统 - 所有权机制在Delphi序列化过程中很重要(Stream.ReadComponent / WriteComponent等)。

答案 6 :(得分:0)

TComponent后代只需要所有者参数,因为它是TComponent构造函数的参数。在设计时可访问以放在TFormTFrameTDataModule类上的所有组件都是TComponent个后代(包括TXMLDocument)。