【问题标题】:Why does TObjectList<T>.Clear not free objects?为什么 TObjectList<T>.Clear 不能释放对象?
【发布时间】:2011-09-24 23:17:49
【问题描述】:

我注意到了

var
  ObjList : TObjectList <TMyObject>;
...
ObjList := TObjectList <TMyObject>.Create (True);
ObjList.Add (TMyObject.Create);
ObjList.Clear;

不释放对象。查看源代码似乎在Clear(继承自TList &lt;T&gt;)中没有触发cnRemoved通知。

我的问题:这是故意的吗?在Clear 的情况下,有什么理由不想收到这些通知?或者这可以被认为是集合类中的一个错误?

编辑

原来是我放的线

inherited Create;

TMyObject 析构函数的顶部,它应该进入构造函数。这就是为什么我收到内存泄漏报告,看起来TObjectList 没有释放这些项目。一看消息来源就说服了我(我被Count 属性困住了)。无论如何感谢您的帮助!

【问题讨论】:

  • 大胆猜测:你是否将TMyObject.Destroy标记为override
  • 你如何测量对象没有被释放?

标签: delphi generics collections delphi-xe


【解决方案1】:

当您调用.Clear 时,该列表会释放拥有的对象。你有一个测试错误。下面的代码示例是在 Delphi XE 上编写的,显示如下:

Calling CLEAR
Object deleted.
Object deleted.
After CLEAR. Press ENTER to free L and Exit.

TList&lt;T&gt;.Clear 中的代码具有欺骗性,因为Count 实际上是一个属性。查看SetCount(),然后查看DeleteRange(),您将在DeleteRange 过程的末尾看到Notify(oldItems[i], cnRemoved) 的代码。


program Project3;

{$APPTYPE CONSOLE}

uses SysUtils, Generics.Collections;

type
  TDelObject = class
  public
    destructor Destroy;override;
  end;

{ TDelObject }

destructor TDelObject.Destroy;
begin
  WriteLn('Object deleted.');
  inherited;
end;

var L:TObjectList<TDelObject>;

begin
  L := TObjectList<TDelObject>.Create(True);
  L.Add(TDelObject.Create);
  L.Add(TDelObject.Create);
  WriteLn('Calling CLEAR');
  L.Clear;
  WriteLn('After CLEAR. Press ENTER to free L and Exit.');
  Readln;
  L.Free;
end.

【讨论】:

    【解决方案2】:

    TList&lt;T&gt;.Clear 调用DeleteRange 来完成这项工作。 DeleteRange 的最后一部分围绕所有调用 Notify 传递 cnRemoved 的项目。

    因此,您对代码的分析是不正确的。 cnRemoved 通知已按时发送并释放拥有的对象。

    【讨论】:

    • 嗯。引用我 33 分钟前的回答:"The code in TList&lt;T&gt;.Clear is deceiving, because Count is actually a property. Look at SetCount(), then look at DeleteRange() and you'll see the code for Notify(oldItems[i], cnRemoved) at the end of the DeleteRange procedure."
    • @Cosmin 我知道。但是您的答案中有大量代码使该消息混乱。如你所知,我喜欢简洁的答案。
    • 你的逻辑很好,你的答案是正确的,但我更喜欢 Cosmin 的答案,因为它有示例代码。尽管如此,我对两者都 +1。
    • @Warren @Cosmin 我认为不需要代码。如果要添加代码,那么检查cnRemoved 通知肯定会更好,因为这是 OP 实际上所说的缺失。是的,我知道一个跟随另一个。
    • @CosminPrund, @warren 你们都是好孩子。感谢您的周到!
    猜你喜欢
    • 1970-01-01
    • 2020-06-26
    • 2021-06-30
    • 2017-01-11
    • 2011-10-05
    • 2017-07-06
    • 2011-11-18
    • 1970-01-01
    • 2010-10-21
    相关资源
    最近更新 更多