如何在Delphi Seattle Firemonkey多设备应用程序中从内存中释放运行时ListBoxItems

时间:2017-02-15 10:23:09

标签: delphi memory listbox firemonkey delphi-10-seattle

我有几个表单,我有一个填充运行时的TListBox组件。

我的问题是如何才能最好地释放我添加运行时的项目?

  • 使用所有者?表格或列表框?
  • 或者自己解放他们?
  • 还是以不同的方式?

下面是我填写列表框的示例:

procedure TForm1.LoadList;
var
  item: TListBoxItem;
begin
  myList.Clear;
  myList.BeginUpdate;
  try
    with myQuery do
    begin
      First;
      while not eof do
      begin
        item := TListBoxItem.Create(nil);
        try
          item.Tag := FieldByName(myIDField).AsInteger;
          item.Text := FieldByName(myDescriptionField).AsString;
          myList.AddObject(item);
        finally
          Next;
        end;
      end;
    end;
  finally
    myList.EndUpdate;
  end;
end;

我确实注意到,当我设置项目的所有者时,创建列表可能需要更长的时间。 此外,当我调用ListBox.Clear并且列表中没有所有者的项目时,列表仍然可以正确清除。这是否意味着当我使用AddObject将它们添加到ListBox时,项目的所有者会被设置?

此外,我通过近距离动作释放表格:

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := TCloseAction.CaFree;
end;

我不知道这是否会改变如何释放列表中的项目?

1 个答案:

答案 0 :(得分:1)

当您执行.AddObject时,您只是将该对象作为父级。

我的建议是像现在一样创建对象,只给他们一个父对象。您也可以这样做而不是.AddObject

item.parent := mylist

正如已经提到的,ARC在移动平台上使用,但在桌面上,在处理对象方面仍然照常使用。

要释放您的物品(无论​​平台如何),您可以这样做:

var
  I: Integer;
begin
    for I := Mylist.Count-1 downto 0 do
    begin
       {$IFNDEF AUTOREFCOUNT}
         Mylist.ItemByIndex(I).DisposeOf
       {$ELSE}
         Mylist.ItemByIndex(I).parent := nil;
       {$ENDIF}
    end;
end;

因为你正在做的是为启用ARC的平台将父设置为nil,导致对象在其引用计数达到0时被释放(假设没有其他对象的引用,如所有者等)。

在非ARC平台上,.DisposeOf只是一个免费电话。 但是,您也可以在ARC平台中使用.DisposeOf,但这会使您的对象处于“Zombie”状态,并且不会被视为关于对象的内存管理的“理想”解决方案。