为什么不是收集TInterfacedObject的后代垃圾? [英] why aren't descendants of TInterfacedObject garbage collected?

查看:107
本文介绍了为什么不是收集TInterfacedObject的后代垃圾?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个基于TInterfacedObject的类。我添加到TTreeNode的Data属性。

  TFacilityTreeItem = class(TInterfacedObject)
private
m_guidItem:TGUID ;
m_SomeOtherNode:TTreeNode;
public
end;

我创建了这个对象的许多实例假设是因为他们被引用,我不应该需要释放它们。但是,当检查这个时,我打开了ReportMemoryLeaksOnShutdown,发现他们没有被释放。



这些对象正在一个放置在主窗体上的框架中创建。在主窗体的FormClose中,我清除树节点,以便每个对象都应该被释放。



发生了什么?



谢谢你的帮助!

解决方案

TInterfacedObject本身不是引用计数,只有接口是。您可以使用TInterfacedObject实现接口,它基本上可以节省您自己实现引用计数方法的工作量。不幸的是,在您的情况下仍然无法工作:编译器不知道您将接口分配给TTreeNode.Data属性,因为它不被声明为接口,而是作为指针。所以各种奇怪的事情都会发生:

  MyInt:= TFacilityTreeItem.Create; // ref count = 1 
// Node.Data:= MyInt; //不会编译
Node.Data:= pointer(MyInt); //没有接口分配,引用计数保留1
...
end; // ref count达到0,你的对象被释放

一旦你尝试访问你的对象.Data属性,您将获得访问冲突。



所以,在这种情况下,不要打扰接口,你可以让它工作,但它会比价值更多的努力。


i have a class based on TInterfacedObject. i add it to TTreeNode's Data property.

TFacilityTreeItem=class(TInterfacedObject)
private
  m_guidItem:TGUID;
  m_SomeOtherNode:TTreeNode;
public
end;

i create many instances of this object & had assumed that because they're reference counted, i shouldn't need to Free them. that'd be handy.

however, when checking this, i turned on ReportMemoryLeaksOnShutdown and found they're not being freed after all.

these objects are being created in a frame that's placed on the main form. in the main form's FormClose, i clear the tree nodes such that every object should be freed.

what's happening?

thank you for your help!

解决方案

TInterfacedObject itself is not reference counted, only interfaces are. You can implement interfaces using TInterfacedObject which basically saves you the effort of implementing the reference counting methods yourself. Unfortunately it still will not work in your case: The compiler does not know that you are assigning interfaces to the TTreeNode.Data property since it is not declared as an interface but as a pointer. So all kinds of weird things will happen:

MyInt := TFacilityTreeItem.Create; // ref count = 1
// Node.Data := MyInt; // won't compile
Node.Data := pointer(MyInt); // no interface assignment, ref count stays 1
...
end; // ref count reaches 0, your object gets freed

As soon as you try to access your object through the .Data property, you will get an access violation.

So, don't bother with interfaces in this case, you could get it to work, but it will be much more effort than it is worth.

这篇关于为什么不是收集TInterfacedObject的后代垃圾?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆