【问题标题】:Create and then destroy TLabels at runtime in Firemonkey在 Firemonkey 运行时创建然后销毁 TLabels
【发布时间】:2015-03-16 19:20:30
【问题描述】:

我正在尝试在运行时生成 TLabels 并使用此代码将它们插入到 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?

【问题讨论】:

    标签: delphi firemonkey destroy tlabel


    【解决方案1】:

    您从以下行开始循环

    for i := 0 to ComponentCount-1 do
    

    但是当您释放一个组件时,它会将自己从组件列表中删除,作为其清理代码的一部分。因此,每个被释放的组件都会将列表的大小减少 1。ComponentCount-1 表达式在 for 循环开始时计算一次,因此不会更新以反映更改。

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

    不过,解决这个问题的方法很简单。只需向后迭代列表:

    for i := ComponentCount-1 downto 0 do
    

    值得一提的是,您的代码实际上只会在 Windows 和 OSX 上释放项目。在移动设备上,编译器使用 ARC,它仅在删除所有引用后才释放对象。解决方案/解决方法/fudge[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] - 取决于您与谁交谈。

    【讨论】:

      猜你喜欢
      • 2019-05-09
      • 2013-10-01
      • 2020-11-20
      • 1970-01-01
      • 2012-09-11
      • 2012-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多