为什么释放 TObjectList 也会删除控件?

Why does freeing TObjectList also deletes controls?

我使用 TObjectList 来处理特定的标签列表。但是当我在 Try Final 中执行推荐的 .Free 时,它​​也会从列表中删除控件。

带有 3 个标签的简单示例:

Procedure GetHeaderLabels(var aList:TObjectList<TLabel>);
begin
  aList.Add(Form1.lblHeaderCars);
  aList.Add(Form1.lblHeaderBrands);
  aList.Add(Form1.lblHeaderModels);
end;

procedure TForm1.Button1Click(Sender: TObject);
var vHeaderLabelsList:TObjectList<TLabel>;
begin
  vHeaderLabelsList:=TObjectList<TLabel>.Create;
  try
     GetHeaderLabels(vHeaderLabelsList);
      {... process Header Labels }
  finally
    vHeaderLabelsList.Free;
  end;
end;

在这种情况下,当我执行此代码时,我最终缺少标签控件 - 它们已从表单中删除,在调试中我看到控件为零。

我不应该.Free TObjectList 吗?如何释放 TObjectlist 并仍然保留控件?

TObjectList 有一个 OwnsObjects 属性,默认情况下是 True。如果您在释放它之前的某个时刻不更改它,它将释放它包含的对象。如果您不希望这样,请将 OwnsObjects 设置为 False

vHeaderLabelsList := TObjectList<TLabel>.Create(False);

如果您不需要 TObjectList 拥有(清理)的对象,最好直接使用 TList:

vHeaderLabelsList := TList<TLabel>.Create;

您偶然发现了 TObjectList and TList<TObject>.

之间的区别

一个TObjectList 'owns'列表中的对象,这意味着默认情况下,当一个对象从列表中删除或列表本身被销毁时,它会销毁其中包含的所有对象.
如果您不希望发生这种情况,请在将项目添加到列表之前使用 TList<TObject> 或将 OwnsObjects 设置为 false。
这通常在构造函数中完成,但您也可以在之后进行设置。

所有这些都在文档中明确指出。

If the entry is owned, when the entry object is removed from the list, the entry object is freed.

The OwnsObjects property gets or sets the object ownership.

你真的应该检查一下:http://docwiki.embarcadero.com 什么时候发生意想不到的事情,然后再赶到 SO :-)。