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

Delphi 10.4中FMX.ListView.TListView重载时内存无法释放问题咨询

解决Delphi 10.4 FMX TListView清空后内存无法释放的问题

核心原因

FMX的TListView调用Clear或逐个Delete项时,部分内部外观对象(如TListItemAppearance派生实例)可能因引用计数未归零、事件绑定未解除,或是组件内部缓存未触发清理,导致内存无法及时释放——哪怕没有位图,自定义外观模板或绑定的事件也可能持有引用。

可行解决方案

1. 强制触发组件资源清理

清空列表后手动调用ReleaseResources,强制释放ListView内部缓存的外观资源;ARC平台(Android/iOS/macOS)可配合重新创建组件彻底清理引用:

if ListView1.Items.Count > 0 then
begin
  ListView1.Items.Clear;
  // 强制释放内部缓存资源
  ListView1.ReleaseResources;
  {$IFDEF AUTOREFCOUNT}
  // ARC平台下重新创建组件,彻底清理所有引用
  System.TObject.FreeNil(ListView1);
  ListView1 := TListView.Create(Self);
  // 恢复原有组件属性(示例:父容器、外观设置)
  ListView1.Parent := Self;
  ListView1.Appearance := TListItemAppearance.ClassName;
  {$ENDIF}
end;

2. 手动解除Item的事件绑定

如果ListView项绑定了自定义事件(如OnClick、OnPaint),删除前需解绑事件,避免事件持有对象引用:

var
  j: Integer;
begin
  for j := ListView1.Items.Count - 1 downto 0 do
  begin
    // 解除项的自定义事件绑定(示例:OnClick)
    ListView1.Items[j].OnClick := nil;
    // 手动释放外观对象
    if Assigned(ListView1.Items.AppearanceItem[j]) then
    begin
      ListView1.Items.AppearanceItem[j].Free;
      ListView1.Items.AppearanceItem[j] := nil;
    end;
    ListView1.Items.Delete(j);
  end;
  ListView1.ReleaseResources;
end;

3. 数据绑定场景的正确清理方式

若使用数据绑定(如绑定TList或TDataSet),不要直接操作Items,先解绑数据源再清空:

// 假设绑定了BindSourceDB1
BindSourceDB1.DataSet := nil;
ListView1.Items.Clear;
BindSourceDB1.Free;
BindSourceDB1 := TBindSourceDB.Create(Self);
// 如需复用,后续重新绑定数据源即可

4. 排查自定义Appearance模板

如果用了自定义ItemAppearance模板,确认模板内控件没有持有外部引用,且项删除时模板实例被正确释放。可临时切换回默认Appearance(如ListItem)测试,排查是否为自定义模板导致的泄漏。

验证方法

启用Delphi自带的FastMM4内存泄漏检测(项目选项中开启「Full debug mode」),清空列表后触发内存快照,对比前后内存变化,确认是否仍有未释放对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 22:07:21