Delphi - 是否需要释放Treeview数据对象?

时间:2014-02-19 12:40:21

标签: delphi memory-management treeview

Delphi 2010 - 我有一个大约有2000个节点的Treeview。每个节点都有一个数据对象,它指向一条记录。当我退出程序时,与Data对象关联的内存是否会自动释放,或者我是否需要遍历每个节点一个DISPOSE?

4 个答案:

答案 0 :(得分:2)

Data类的TTreeNode属性旨在供您用于私人需求。它是一个无类型的指针,可让您自由地放置任何您喜欢的内容。

作为属性是无类型指针的推论,控件无法知道你放在那里的东西是什么类型。因此即使它想要它也不能破坏它。

所以是的,你确实需要确保你分配的内存被破坏了。基本上你是该内存的拥有者,控件不拥有它。

你如何做到这一点当然完全取决于你。一种选择是拥有一个拥有与每个节点相关的数据的独立容器。然后,您可以删除容器并让它删除数据。

如果您的复杂树结构很难在可用的容器中复制,那么这可能会很不方便。在这种情况下,您可以选择自定义树视图以创建您定义的类型的节点。该自定义节点类型可以负责分配和取消分配数据。 OnCreateNodeClass是实现这一目标的关键。

答案 1 :(得分:1)

通过谷歌搜索发现了这个问题而没有找到我刚才使用的解决方案,即使这个问题已经存在了几年,我仍然决定回答。

TTreeView有一个OnTreeDeletion方法,在树中的每个节点被删除时调用该方法,从而有机会释放/处理任何相关数据。

这是我的代码:

procedure TfmMyForm.MyTreeDeletion(Sender: TObject; Node: TTreeNode);
var
  rci: TRecentCodeItem;
begin
  rci := node.data;

  if assigned(rci) then
    freeandnil(rci);
end;

我使用节点存储指向TRecentCodeItem类型的对象的指针。

我的情况和提问者之间的一个区别是我的树形视图不在主窗体上,所以我不能将它留在窗口以便在应用程序关闭后擦除内存。不管怎样我都不会这样做 - 我确实希望零内存泄漏。

答案 2 :(得分:0)

是的,一旦退出程序,数据就会被释放,因为对象位于应用程序运行的进程的同一内存空间中。最好使用Object.free或更好地手动释放它们{ {1}}。

答案 3 :(得分:0)

我使用这种疗法,也许它可以帮助将来的某个人:

TTreeViewItemEx<TData: class> = class(TTreeViewItem)
private
    _dataObject: TData;
public
    destructor Destroy; override;
    property dataObject: TData read _dataObject write _dataObject;
end;

destructor TTreeViewItemEx<TData>.Destroy;
begin
    if Assigned(_dataObject) then
        _dataObject.Free;

    inherited;
end;

用法:

procedure UsageExample;
var
    node: TTreeViewItemEx<TData>;
begin
    node := TTreeViewItemEx<TData>.Create(treeView);
    node.DataObject := TData.Create;
    node.Parent := treeView;
end;