德尔福所有权混乱 [英] Delphi Ownership Confusion

查看:187
本文介绍了德尔福所有权混乱的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直认为,所有者负责销毁视觉控制,如果我通过 nil 作为所有者,我可以手动控制销毁。



考虑以下示例:

  TMyForm =类(TForm)
private
FButton:TButton;
结束

...
FButton:= TButton.Create(nil); //没有主人!
FButton.Parent:=自我;

我希望这个按钮产生内存泄漏,但实际上并不是析构函数 TButton 被调用。



进一步调查显示, TWinControl 析构函数包含以下代码片段:

  I:= ControlCount; 
,而I< 0 do
begin
实例:=控件[I - 1];
删除(实例);
Instance.Destroy;
I:= ControlCount;
结束

看起来它正在破坏子组件(带有 Parent 设置为控件本身)。



我并不期望父控件破坏控件。任何人都可以解释为什么会发生这种情况?如果我通过一个所有者,谁在摧毁对象?

解决方案


为什么会发生这种情况?


它是有意义的,它的设计。当父母被毁坏时,你认为孤儿控制会发生什么?他们应该突然开始浮动在顶层窗户?可能不会。他们应该重新接受另一个控制吗?哪一个?

 如果我传递所有者,谁正在摧毁对象? 

,如果它被分配和被释放第一。 TWinControl 覆盖 TComponent 的析构函数释放其子控件第一个(继承的析构函数是后来才叫)。孩子控制通知他们的所有者被破坏,将它们从其所有组件列表中删除。这就是为什么所有者不会在其析构中再次释放你的对象。



如果是与所有者相同的对象,那么上面也适用。



如果所有者是两个不同的对象,您先释放所有者,然后所有者组件释放其所有的所有组件(请参阅 TComponent 的析构函数)。您的对象是一个 TControl 后代, TControl 覆盖析构函数以调用 SetParent(nil); ,从父列表中删除该实例的儿童控制。这就是为什么父进程不会在析构函数中再次释放你的对象。


I always thought that the owner is responsible for destroying visual controls and that I can manually control destruction if I pass nil as the owner.

Consider the following example:

TMyForm = class (TForm)
private
  FButton : TButton;
end;

...
FButton := TButton.Create(nil);   // no owner!!
FButton.Parent := Self;

I would expect this button to produce a memory leak but it doesn't and in fact the destructor of TButton is called.

Further investigation showed that the TWinControl destructor contains the following snippet of code:

I := ControlCount;
while I <> 0 do
begin
  Instance := Controls[I - 1];
  Remove(Instance);
  Instance.Destroy;
  I := ControlCount;
end;

which looks like it is destroying the child components (the ones with Parent set to the control itself).

I was not expecting the parent control to destroy the control. Can anybody explain why this is happening? And who is destroying the object if I pass in an owner?

解决方案

why this is happening?

It makes sense and it's by design. What do you think should happen to orphaned child controls when the parent is destroyed? Should they suddenly start floating around as top-level windows? Probably not. Should they be re-parented to another control? Which one?

who is destroying the object if I pass in an owner?

Parent, if it's assigned and being freed first. TWinControl overrides TComponent's destructor to free its child controls first (the inherited destructor is only called later). The child controls notify their Owner about being destroyed which removes them from its list of owned components. That's why the Owner doesn't attempt to free your object again later in its destructor.

If Parent is the same object as Owner then the above applies, too.

If Parent and Owner are two different objects, and you free the Owner first, then the Owner component frees all its owned components (see TComponent's destructor). Your object is a TControl descendant and TControl overrides the destructor to call SetParent(nil); which removes the instance from the parent's list of child controls. That's why the parent doesn't attempt to free your object again later in its destructor.

这篇关于德尔福所有权混乱的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆