delphidelphi-10.1-berlintobjectlist

Why does freeing TObjectList also deletes controls?


I use TObjectList to process specific list of labels. But when I do the recommended .Free in Try Final, it also deletes the controls from the list.

Simple example with 3 labels:

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;

In this case when I execute this code I end up with missing label controls - they are deleted from the form and in debug I see that controls are nil.

Am I not supposed to .Free TObjectList? How can I Free TObjectlist and still keep the controls?


Solution

  • TObjectList has an OwnsObjects property, which by default is True. If you don't change that at some point before you free it, it will free the objects it contains. If you don't want that, then set OwnsObjects to False.

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

    If you don't need the objects owned (cleaned up) by the TObjectList, it would be better to simply use TList instead:

    vHeaderLabelsList := TList<TLabel>.Create;