You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi中释放TFDMemTable存储的运行时创建TPanel组件遇无限循环求助

问题根源

你当前的代码在遍历TFDMemTable时直接释放TPanel,释放操作大概率间接触发了数据集的游标重置(比如Panel关联的组件触发了数据集相关事件),导致每次执行FreeAndNil后,数据集游标自动回到第一条记录,进而陷入First→遍历→重置回First的无限循环。

正确的释放步骤

别在遍历数据集的同时释放对象,先把所有需要销毁的TPanel指针收集到临时容器里,再统一释放,避免操作对象时干扰数据集的遍历状态:

procedure TDataForm.PicturesBeforeClose(DataSet: TDataSet);
var
  PanelList: TList;
  I: Integer;
  PanelPtr: NativeInt;
begin
  PanelList := TList.Create;
  try
    // 1. 先把所有Panel的指针收集到列表里
    Pictures.First;
    while not Pictures.Eof do
    begin
      PanelPtr := Pictures.FieldByName('Panel').AsLargeInt;
      if PanelPtr <> 0 then // 跳过空指针
        PanelList.Add(Pointer(PanelPtr));
      Pictures.Next;
    end;

    // 2. 遍历列表统一释放Panel
    for I := 0 to PanelList.Count - 1 do
    begin
      try
        TPanel(PanelList[I]).Free;
      except
        ShowMessage('释放Panel失败:' + Exception(ExceptObject).Message);
      end;
    end;
  finally
    PanelList.Free; // 别忘了释放临时列表
  end;
end;
关键细节提醒
  • 指针存储要兼容64位:别用Integer存指针地址,64位系统下Integer是32位,会截断64位指针导致释放出错。改用NativeInt适配不同位数系统,赋值语句改成:
    Pictures.FieldByName('Panel').AsLargeInt := NativeInt(TPanel.Create(nil));
    
  • 用Free代替FreeAndNil:这里直接通过指针释放对象,FreeAndNil需要操作变量,用Free更直接合适。
  • 如果Panel有父容器,Free会自动将其从父容器的控件列表中移除,无需额外处理。

内容的提问来源于stack exchange,提问作者user3140961

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 16:33:30