【发布时间】:2016-06-11 08:06:02
【问题描述】:
我正面临以下情况,我想知道这段代码是否泄漏了内存。 假设我有以下接口和实现:
type
ITools = interface
function HelloWorld : String;
end;
IDatabase = interface
function Query(AQuery : String) : String;
end;
IManager = interface
procedure Execute;
end;
TDatabase = class(TInterfacedObject, IDatabase)
strict private
FTools : ITools;
public
constructor Create;
destructor Destroy; override;
function Query(AQuery : String) : String;
end;
TTools = class(TInterfacedObject, ITools)
strict private
FDatabase : IDatabase;
public
constructor Create(ADatabase : IDatabase);
destructor Destroy; override;
function HelloWorld : String;
end;
TManager = class(TInterfacedObject, IManager)
strict private
FDatabase : IDatabase;
public
constructor Create;
procedure Execute;
end;
现在,如果你创建例如这个:
procedure Example;
var
lExample : IManager;
begin
lExample := TManager.Create;
lExample.Execute;
lExampe := nil; // Should not be necessary
end;
其中TManager 中的FDatabase 被创建为TDatabase 并传递给TTools 的构造函数,因此它在TTools 中与在TManager 中具有相同的(?)对象/接口。
然后lExample 泄漏内存,因为子类中的接口/对象(IDatabase)。为什么不发布接口?或者我对 Delphi 基础知识有哪些不了解的地方?
【问题讨论】:
-
问题一旦提出就很容易回答了。
-
是的,有循环引用。数据库有一个对工具的strong 引用,它有一个对数据库的strong 引用。引用计数系统中的经典内存泄漏。这些引用之一需要改为 weak 引用。但是,XE7 中尚不支持弱接口引用,最近在 10.1 Berlin 中添加了该引用(请参阅blog.marcocantu.com/blog/…)。在早期版本中,您必须求助于使用
Pointer和类型转换来完成同样的事情。 -
请参阅:blog.dummzeuch.de/2014/06/19/… 以获得 XE7 的解决方案
标签: delphi delphi-xe7