在我的代码中,我使用了一个在不同地方创建的小型数据存储类。为了避免内存泄漏和简化,我想使用引用计数,所以我做到了。
type TFileInfo = class (TInterfacedObject, IInterface)并删除了我对TFileInfo.Free的所有手动调用。不幸的是,Delphi报告了大量内存泄漏。通过搜索,我发现了以下问题,解释了为什么这不起作用:
为什么没有收集TInterfacedObject垃圾的后代?
这里有一个解决方案,但它要求我(至少如果我做对了)编写一个自定义接口IFileInfo,并为它提供大量的getter和setter,这是我想要避免的。
编辑--我应该将create FileInfo对象插入到两种不同类型的哈希表中:一种是从TBucketList降序的哈希表,另一种是来自Codegear论坛的哈希映射实现。在内部,它们都是用户指针,所以情况就像在另一个问题中一样。
在Delphi中是否还有其他可能使用引用计数来生成对象?
发布于 2009-04-23 10:42:10
不幸的是,Delphi编译器只在使用接口(在您的例子中是自定义接口IFileInfo)时才生成必要的代码到inc/dec引用计数。此外,如果接口被转换为指针(或TObject ),则同样不可能进行引用计数。例如,假设全局变量列表: TList:
var ifi : IFileInfo;
begin
ifi := TFileInfo.Create;
list.Add(TFileInfo(ifi));
end;方法返回后,listlist.Count -1将包含悬空指针。
因此,不能在将接口转换为指针的hashmap中使用接口,因此hashmap实现必须将它们保持为IInterface。
发布于 2009-04-23 17:03:51
只有当您只有通过接口引用实例时,Delphi中的引用计数才能工作。一旦将接口引用和类引用混合在一起,就会遇到麻烦。
本质上,您需要引用计数,而不需要创建包含其中定义的所有方法和属性的接口。有三种方法可以做到这一点,这些方法大致按我推荐的顺序排列。
这就是德尔菲的问题,有一种免费的方法来完成一些事情。选项1是最好的,在我看来-得到德尔菲2009,并使用该方法,如果你可以的话。
祝好运!
发布于 2009-04-23 14:37:16
不要混合对象引用和接口引用。
var
Intf: IInterface;
Obj: TFileInfo;
begin
// Interface Reference
Intf := TFileInfo.Create; // Intf is freed by reference counting,
// because it's an interface reference
// Object Reference
Obj := TFileInfo.Create;
Obj.Free; // Free is necessary
// Dangerous: Mixing
Obj := TFileInfo.Create;
Intf := Obj; // Intf takes over ownership and destroys Obj when nil!
Intf := nil; // reference is destroyed here, and Obj now points to garbage
Obj.Free; // this will crash (AV) as Obj is not nil, but the underlying object
// is already destroyed
end;https://stackoverflow.com/questions/781100
复制相似问题