繁体   English   中英

在Firemonkey的运行时创建并销毁TLabel

[英]Create and then destroy TLabels at runtime in Firemonkey

我正在尝试在运行时生成TLabel,并使用以下代码将它们插入VertScrollBox;

var
   i, f: integer;
   RT_Label: TLabel;
begin
   f:= 10;
   for i := 0 to 20 do
   begin
        RT_Label := TLabel.Create(Self);
        RT_Label.Name := 'Label' + i.ToString;
        RT_Label.Text := 'SampleLabel' + i.ToString;
        RT_Label.Position.Y := f;
        RT_Label.Align := TAlignLayout.Top;
        RT_Label.Parent := VertScrollBox1;
        inc(f, 15);
   end;
end; 

标签显示没有问题,但是当我尝试使用以下代码释放生成的标签时:

var
   i: integer;
   LComponent: TComponent;
begin
   for i := 0 to ComponentCount-1 do
   begin
        if( Components[i] is TLabel )then
         if StartsText('Label', (Components[i] as TLabel).Name) then
         begin
             LComponent := (Components[i] as TLabel);     
             If Assigned(LComponent) then FreeAndNil(LComponent);
         end;
    end;
end;

然后,我总是收到错误“参数超出范围”。

如何在运行时正确删除添加到VertScrollBox的TLabel?

您可以从以下行开始循环

for i := 0 to ComponentCount-1 do

但是当您释放组件时,它会作为清理代码的一部分从“组件”列表中删除。 因此,释放的每个组件都会将列表的大小减小1。在for循环启动时, ComponentCount-1表达式将被评估一次,因此不会进行更新以反映更改。

即使您可以解决此问题,循环也会跳过项目。 即,如果您删除的项目3,项目4现在将变为项目3,但您的循环将前进到项目4。

但是,解决此问题的方法很简单。 简单地向后迭代列表:

for i := ComponentCount-1 downto 0 do

值得一提的是,您的代码实际上只会在Windows和OSX上免费提供项目。 在移动设备上,编译器使用ARC,只有在删除了所有引用后,ARC才会释放该对象。 解决方案/解决方法/错误[1]是为组件调用DisposeOf而不是Free

顺便说一句, as运算符已经保证对象已Assigned ,因此不需要额外的测试。 无需FreeAndNil一个局部变量,该局部变量将被重新分配或直接超出范围,并且无需在释放对象之前强制转换对象。 由于Free(或DisposeOf )方法存在于公共祖先类中,因此编译器将解析任何后代类的链接。

因此,您的代码可以简化为:

var
  i: integer;
begin
  for i := ComponentCount-1 downto 0 do
  begin
    if Components[i] is TLabel then
      if StartsText('Label', (Components[i] as TLabel).Name) then
        Components[i].DisposeOf;
  end;
end;

[1]-取决于您与谁交谈。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM