为什么TObjectList <t> .Clear不是自由对象?</t>

时间:2011-06-29 08:53:21

标签: delphi generics collections delphi-xe

我刚刚注意到了

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

不会释放该对象。查看源代码,似乎cnRemoved中没有触发Clear通知(继承自TList <T>)。

我的问题:这是故意的吗?在Clear的情况下,是否有人不希望收到这些通知?或者这可以被视为集合类中的错误?

修改

原来我把线放了

inherited Create;

位于TMyObject析构函数的顶部,它应该进入构造函数。这就是我报告内存泄漏的原因,看起来TObjectList没有释放这些项目。看一下来源说服了我(我被Count财产困住了)。无论如何,谢谢你的帮助!

2 个答案:

答案 0 :(得分:15)

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

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

TList<T>.Clear中的代码是骗人的,因为Count实际上是一个属性。查看SetCount(),然后查看DeleteRange(),您会在Notify(oldItems[i], cnRemoved)程序结束时看到DeleteRange的代码。


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.

答案 1 :(得分:8)

TList<T>.Clear致电DeleteRange来完成工作。 DeleteRange的最后一部分围绕通过Notify调用cnRemoved的所有项目运行。

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