我有一个装有单个控件的容器。此控件可以是少数几种类型之一(TMyFrame
后代)。控件正在运行时创建和销毁。
在某些时候我需要释放和 nil这个控件:
var
C: TControl;
C := SomeForm.MyContainer.Controls[0];
C.Free;
C := nil;
但问题是控件实例本身未设置为nil。
这可能吗?
我想关键点是一个实例可以有很多引用它。我刚刚意识到一个引用不能"看到"所有其他未知参考文献。
答案 0 :(得分:2)
无法填充对象实例,在这种情况下,不需要将任何引用设置为nil
。
如果Container.Controls[0]
有效,则Container
是控件的父级。当您释放该控件时,VCL负责从父级中提取已离去的子项,因此在您释放Container.Controls[0]
后,ControlCount
将为0
且Container.Controls[0]
将无效
答案 1 :(得分:2)
<强>更新强>
根据您的评论,在动态创建控件时,您不会存储对控件的引用。在这种情况下,您无需将任何内容设置为nil
。
VCL框架本身包含对控件的各种引用。但这些都是由框架管理的。你提到
ActiveControl
。如果销毁活动控件,则框架负责管理ActiveControl
属性。
除了破坏控件之外,你无需做任何事情。 您不需要清除参考,因为您没有参考。
有一种机制可以自动设置对nil
的引用。它在TComponent
中实施。在TComponent
的析构函数中,调用了SetReference(False)
并且实现了这样的实现:
procedure TComponent.SetReference(Enable: Boolean);
var
Field: ^TComponent;
begin
if (FOwner <> nil) then
begin
Field := FOwner.FieldAddress(FName);
if Field <> nil then
if Enable then Field^ := Self else Field^ := nil;
end;
end;
所以,假设你有一个这样的表格:
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button2Click(Sender: TObject);
end;
这两个按钮是由表单流框架创建的。假设在Button2Click
中你写Button1.Free
。然后,对SetReference
的调用会将Button1
变量设置为nil
。
现在,您正在讨论在运行时创建的控件。您没有告诉我们您如何定义未设置为nil
的引用。如果您想安排引用自动设置为nil
,则需要执行以下操作:
Owner
。Name
与您在步骤1中声明的已发布字段相同。如果你不能这样做,那么你需要手动编写代码来设置对nil
的引用。这样做:
SomeReference := nil;
现在,我不知道你将如何掌握SomeReference
。只有你能知道。因为只有您知道要将此引用设置为nil
的位置。
或者整个问题可能是一个完全的误解。也许您没有对动态创建的控件的引用。在这种情况下,使用Controls[]
或其他方法找到控件,调用Free
,然后完成作业。