0

I have a few forms where I have a TListBox component that I fill runtime.

My question is how can I best free the items that I add runtime?

  • By using the owner? Form or ListBox?
  • Or freeing them myself?
  • or a different way?

Below an example how I fill my listbox:

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;

I do have noticed that creating the list may take a bit longer when I set the owner of the item. Also when the I call ListBox.Clear and the list was filled with items with no owners the list still gets cleared correctly. So does this mean the owner of the items get set when I use AddObject to add them to the ListBox?

Also I Free the form with the close action:

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

I don't know if this changes things how to free the items in my list?

Remi
  • 1,289
  • 1
  • 18
  • 52
  • Firemonkey uses ARC (Automatic Reference Counting) as a means for memory management. I suggest you read what [Embarcadero says about it](http://docwiki.embarcadero.com/RADStudio/Seattle/en/Automatic_Reference_Counting_in_Delphi_Mobile_Compilers) for a starter. – Tom Brunberg Feb 15 '17 at 10:53
  • @TomBrunberg I've read the page, but I'm still not totally sure what is best for my situation. It doesn't really cover visual components or lists so – Remi Feb 15 '17 at 12:49
  • 1
    FMX does not impose ARC. Next gen compilers use ARC as memory management. On desktop, FMX uses the same memory management as the Vcl, ie ownership based – Agustin Ortu Feb 15 '17 at 13:30
  • @AgustinOrtu so I need to set the owner of the item? And set it to the form or the list? – Remi Feb 15 '17 at 14:03
  • 1
    The owner of the items should be the ListBox – Agustin Ortu Feb 15 '17 at 19:24

1 Answers1

1

When you do a .AddObject you are just giving that object a parent.

My suggestion would be to create the objects as you do now, only giving them a parent. Instead of doing a .AddObject you can also do :

item.parent := mylist

And as has been mentioned, ARC is used on mobile platforms but on desktop it is still business as usual in regards to working with objects.

To free your items (regardless of platform) you could do this :

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;

Because what you are doing then is setting the parent to nil for ARC enabled platforms, resulting in the object being freed once its reference count reaches 0 (given that there are no other references to the object like an owner etc).

And on non-ARC platforms the .DisposeOf will simply be a call to free. You can however also use .DisposeOf in ARC platforms too, but this will leave your objects in a "Zombie" state and is not considered the "ideal" solution to memory management regarding objects.

Edrean Ernst
  • 370
  • 1
  • 14
Peter-John Jansen
  • 603
  • 1
  • 7
  • 26
  • setting a TFmxObject parent property just calls the addObject method so that makes no difference. – Remi Feb 16 '17 at 15:07
  • @Remi , Yes, setting a parent and calling `AddObject` comes down to the same, I was just saying that you could also do it by setting the parent, but my answer does address your initial question regarding freeing objects? – Peter-John Jansen Feb 20 '17 at 08:13
  • Why do you use ItemByIndex? Why not MyList.Items or MyList.ListItems? And do you have any documentation supporting your answer? – Remi Feb 20 '17 at 14:41
  • 1
    Because `mylist.items` is the items as strings, which will only give you the items as strings, and `ListItems` will eventually lead to a call of `Itembyindex` in `FMX.Listbox` you will see that the ListItems property when read does a `GetListItem` which then calls `ItemByIndex` – Peter-John Jansen Feb 20 '17 at 15:03
  • 1
    You can read all about references and disposeOf and the zombie state here http://docwiki.embarcadero.com/RADStudio/Seattle/en/Automatic_Reference_Counting_in_Delphi_Mobile_Compilers, but I would suggest you look at David's answer here : http://stackoverflow.com/questions/27818697/how-to-free-a-component-in-android-ios – Peter-John Jansen Feb 20 '17 at 15:06