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?
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?
Parent, if it’s assigned and being freed first.TWinControloverridesTComponent‘s destructor to free its child controls first (the inherited destructor is only called later). The child controls notify theirOwnerabout 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
Parentis the same object asOwnerthen the above applies, too.If
ParentandOwnerare two different objects, and you free the Owner first, then the Owner component frees all its owned components (seeTComponent‘s destructor). Your object is aTControldescendant andTControloverrides the destructor to callSetParent(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.