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