【问题标题】:Clear a TList or a TObjectList清除 TList 或 TObjectList
【发布时间】:2012-05-02 08:15:17
【问题描述】:

我对在列表中存储对象使用什么感到有点困惑。 到目前为止,我一直使用TList 并在循环中释放每个项目。然后我发现TObjectListFree 自动执行此操作。然后我从TList.Clear的文档中看到了这个:

调用Clear清空Items数组并将Count设置为0。Clear也 释放用于存储Items 数组的内存并将Capacity 设置为0。

所以基本上是一样的。所以

TList

mylist.Clear;
myList.Free;

TObjectList一样吗?

myList.Free;

TObjectList 可以仅用于作为类的项目还是可以存储记录?

【问题讨论】:

  • 如果你不仔细阅读TObjectList文档,你引用的部分只是“基本相同”:“如果OwnsObjects属性设置为true(默认),TObjectList控制它的内存对象,当它的索引被重新分配时释放一个对象;当它使用 Delete、Remove 或 Clear 方法从列表中删除时;或者当 TObjectList 实例本身被销毁时。 TList 的文档没有说明这种行为。这是两个类之间的根本区别。

标签: delphi delphi-2007 tlist


【解决方案1】:

1. TList 不会释放元素,ClearFree

aList.Clear;

将只设置aList.Count := 0 而不释放aList.Items[] 元素。所以你会泄漏内存。您将需要这样的明确免费:

for i := 0 to aList.Count-1 do
  TObject(aList[i]).Free;

但这就是TObjectList 所做的... :)

关于TObjectList,值得一提的是TObjectList.Destroy正在调用Clear

所以

aObjectList.Clear;
aObjectList.Free;

完全一样

aObjectList.Free;

2。要存储记录列表,可以使用动态数组。

您将通过我们的dynamic array wrapper 获得所有TList 方法(以及更多)。也就是Add / Delete / Clear / Count / IndexOf / Find...

它具有内置的序列化功能(二进制或 JSON)、自动排序和比较(使用 RTTI),这些功能在 TList/TObjectList 中是不存在的。从 Delphi 5 及更高版本开始。

使用更现代的 Delphi 版本,如果您不想使用第三方库,可以使用 generics 来处理动态数组。

【讨论】:

  • 只是澄清一下TObjectList。它有一个属性:OwnsObjects(默认 = true),它控制在删除项目时是否释放列表中的对象。
  • @LURD 你是对的。这个属性可能很方便,但也有误导性:您可能认为对象将被释放,但如果您在代码中的某处(即使在运行时)设置OwnObjects := false,您很容易泄漏内存或资源:所以要小心使用!我更喜欢清晰的TList / TObjectList 分隔符。
【解决方案2】:

这不一样TList.Clear 只释放分配用于存储指针的内存,而不是它们指向的对象。 为避免内存泄漏,您需要自己释放内存 - 正如您一直在做的那样 - 或使用 TObjectList

回答第二个问题,TObjectList 不支持存储记录。在这种情况下,您需要使用 TList(或其他东西)。

【讨论】:

  • 知道在TList 中管理记录需要相当多的努力。
【解决方案3】:

仔细阅读文档中的内容:

清除还释放用于存储 Items 数组的内存

仅释放数组本身的内存,而不是数组内单个元素使用的内存。

【讨论】:

    【解决方案4】:

    如果您使用的是最新版本的 Delphi,我建议您使用通用列表。

    现在,当您使用列表中的对象时,您可能需要进行大量转换。有了通用列表,您就不必再这样做了。

    例如,如果您有:

    TMyObject = class(TObject);
    

    然后你可以这样列出:

    TMyObjectList = TObjectList<TMyObject>;
    

    Embarcadero Wiki 中有一篇文章:

    http://docwiki.embarcadero.com/CodeExamples/XE8/en/Generics_Collections_TObjectList_(Delphi)

    【讨论】:

      【解决方案5】:

      真正观看 contnrs.pas 中的 TObjectList 代码 OwnObjects 没有任何作用。 FOwnObjects 是在TObjectList 的私有部分中声明的变量,在TObjectList 代码中的任何地方都没有使用(除了分配值),并且其中没有覆盖Clear 过程。

      所以恐怕有必要像TList一样释放内存。

      【讨论】:

      • 属性TObjectList.OwnsObjects默认为true。您可以在创建后更改属性值。如果调用TObjectList.Free时该属性为真,则列表中的所有对象将被自动释放。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多