簡體   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