Delphi 在 TObjectList<T> 上调用 .Clear 在包含的对象上调用析构函数

问题描述

我有一个项目,其中有一个包含 TObjectList 的模型类。当我使用 clear 函数清空列表时,列表包含一组计算对象,然后我对对象执行一些操作(我将对象引用到其他类字段)。但是当我调用 clear 函数时,我可以看到使用调试器对列表中的对象调用了 Destroy 函数,从而造成访问冲突。

从 delphi 文档中可以看出,Clear 函数不应该尝试释放对象,但它看起来好像确实调用了销毁/解构。

解决方法

当我调用 clear 函数时,我可以看到使用调试器对列表中的对象调用了 Destroy 函数

也就是说,从字面上看,TObjectListTList 更具有定义性。 TObjectList 有一个 OwnsObjects 属性,默认情况下为 true。根据文档:

http://docwiki.embarcadero.com/Libraries/en/System.Contnrs.TObjectList

使用 TObjectList 来存储和维护对象列表。 TObjectList 提供了添加、删除、重新排列、定位、访问和排序对象的属性和方法。如果 OwnsObjects 属性设置为 true(默认值),则 TObjectList 控制其对象的内存,在重新分配索引时释放对象; 当它使用 DeleteRemoveClear 方法从列表中删除时;或者当 TObjectList 实例本身被销毁时。

因此,如果您需要在将对象从列表中删除后继续访问它们,则可以:

  • OwnsObjects 设置为 false。

  • 使用 TObjectList.Extract() 方法删除单个对象而不释放它们。

  • 不要使用会破坏对象的容器。

从 delphi 文档中可以看出,Clear 函数不应该尝试释放对象,但它看起来好像确实调用了销毁/解构。

我不知道您在阅读什么文档,但以上引文摘自 TObjectList 的文档,它显然与您声称的相反。