我刚刚注意到了
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
财产困住了)。无论如何,谢谢你的帮助!
答案 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
通知已正式发送,并且已释放拥有的对象。