【问题标题】:Problems with memory leaks using interface?使用接口的内存泄漏问题?
【发布时间】:2013-12-08 12:50:10
【问题描述】:

我有一个返回IInterface 的方法,该方法包含一个这样创建的字典:

Dictionary:= TDictionary<string, IInterface>.Create;

包含:

Dictionary.Add('key', TPerson.Create(DatabaseCon)as IInterface);

当我退出正在进行的程序时,我收到一条错误消息内存泄漏对象 Tperson

我在类析构函数中尝试了以下方法:

  private //Global variabels
    Person:TPerson;
    I: IInterface;

begin // in the destructor method of the class
   Person:= IInterface as TPerson;
   Person.Free;
end;

但我仍然收到错误消息...如何释放TPerson.Create(DatabaseCon) as IInterface)? 或者将TPerson保存为INI文件中的字符串,然后将字符串名称拖出并变成对象会更好。但是如何??

程序的结构:

Inf1= Interface(IInterface)
//some functions 
Inf2=Interface(Inf1)
//Some functions
TPerson= class(TInterfacedPersistent,Inf2)
// All my functions.

如果我满足以下条件,我可以让它工作:

Dictionary.Add ('key', Person) as IInterface);

我在类的 Create 方法中写:

Person:= TPerson.Create(DatabaseCon);

并在析构方法中写道:

Person.Free;

但是这样做有错吗?因为当我访问字典时必须首先实例化班级人员?

【问题讨论】:

    标签: delphi delphi-xe4


    【解决方案1】:

    最可能的解释是TPerson 不使用接口引用计数来管理生命周期。可以肯定的是,我们需要确切地知道TPerson 是如何实现IInterface 的。不幸的是,问题中省略了关键细节。

    如果TPerson 派生自TInterfacedObject,并且生命周期由引用计数管理,那么您的代码将不会泄漏。因此,我有理由相信,问题在于您的类的 IInterface 实现在其引用计数为零时不会释放该对象。

    假设我是正确的,那么您有几个选项可以解决这个问题:

    1. 更改您的类以实现接口引用计数生命周期管理。
    2. 使用TObjectDictionary&lt;TKey,TValue&gt; 而不是TDictionary&lt;TKey,TValue&gt;。安排值类型TValueTPerson 而不是IInterface。并安排字典拥有其值,以便在删除它们时释放它们。

    更新:您的更新表明我的预感是正确的。您的类不使用接口引用计数来管理生命周期。

    【讨论】:

    • 你继承自 TInterfacedPersistent 所以大卫是对的。 TInterfacedPersistent 的 AddRef & Release 的实现是将这个委托给所有者。很可能你没有,所以你没有引用计数。您应该从 TInterfacedObject 继承或为它提供执行引用计数的所有者或自己在 TPerson 中实现引用计数。
    • 使用 TInterfacedObject 后它就可以工作了。非常感谢 David 和 Lieven ;-)
    猜你喜欢
    • 1970-01-01
    • 2016-07-28
    相关资源
    最近更新 更多