删除表单上某个类的所有组件(Delphi)

Jam*_*amo 12 forms delphi components

这可能是一个愚蠢的问题,但我的大脑已经足够熟了我想我将使用我的一条"生命线"来看看我是否可以从我的堆栈溢出的朋友那里得到一些帮助.;)

我需要删除主表单上所有特定组件类型的出现(其中一些是在面板或标签页内,但全部在同一表单上并由其拥有).这就是我现在拥有的:

for i := 0 to frmMain.ComponentCount - 1 do  
  begin  
    if frmMain.Components[i] is TMyClass then frmMain.Components[i].Destroy;  
  end;    
Run Code Online (Sandbox Code Playgroud)

问题是(我知道它将在我编译之前),一旦我销毁组件,表单的组件列表重新索引,我最终超出界限.

解决这个问题的最佳方法是什么?我想过将"found"组件添加到一个独立的数组中,然后在循环之后遍历它以删除它们,我认为这将起作用....但这是最好的方法吗?

TIA


更新:

你们好棒.谢谢.:)

Bri*_*ost 27

你几乎是对的.你的循环应该是这样的

for i := frmMain.ComponentCount - 1 downto 0 do
begin
  if frmMain.Components[i] is TMyClass then
    frmMain.Components[i].Free;
end;
Run Code Online (Sandbox Code Playgroud)

这样,对函数"frmMain.ComponentCount"的调用在开始时完成而不是再次完成.

你也应该如上所述召唤Free,而不是Destroy - 我现在不记得为什么.BRI

  • 毁灭是虚拟的.如果对象已被破坏,那么它将失败.在调用Destroy之前,自由检查它是否有有效的引用.这里不太可能是一个问题,但总的来说是一个好习惯. (4认同)
  • 在这种情况下,只需调用Destroy是安全的.由于VCL管理此列表的方式,该列表中不可能存在无效引用.即使有,Free也不会保护你,因为它依赖于实例为零. (2认同)
  • 另请注意,循环从高到零,以确保考虑所有项目,否则循环可以跳过已删除项目旁边的项目.重要的是不要错过. (2认同)

jro*_*nhi 10

从顶部开始向后工作.

即:

for i := frmMain.ComponentCount - 1 downto 0 do
begin
  if frmMain.Components[i] is TMyClass then frmMain.Components[i].Free;
end; 
Run Code Online (Sandbox Code Playgroud)

免费呼叫而不是毁灭.检查有效参考后免费调用Destroy.