2017-02-15 29 views
0

У меня есть несколько форм, где у меня есть компонент TListBox, который я заполняю во время выполнения.Как освободить время выполнения ListBoxItems из памяти в Delphi Seattle Firemonkey Multi Device App

Мой вопрос в том, как я могу лучше всего освободить элементы, которые я добавляю во время выполнения?

  • Использование владельца недвижимости: Форма или ListBox?
  • Или освободить их самостоятельно?
  • или по-другому?

Ниже приведен пример, как я заполняю мой 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; 

Я заметил, что создание списка может занять немного больше времени, когда я установить владельца пункта. Также, когда я вызываю ListBox.Clear и список заполнен элементами без владельцев, список по-прежнему очищается правильно. Значит ли это, что владелец предметов устанавливается, когда я использую AddObject, чтобы добавить их в ListBox?

Также я Освободить форму с близким действием:

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

Я не знаю, если это изменяет вещи, как освободить элементы в моем списке?

+0

Firemonkey использует ARC (Automatic Reference Counting) как средство управления памятью. Я предлагаю вам прочитать, что [Embarcadero говорит об этом] (http://docwiki.embarcadero.com/RADStudio/Seattle/en/Automatic_Reference_Counting_in_Delphi_Mobile_Compilers) для стартера. –

+0

@TomBrunberg Я прочитал эту страницу, но я все еще не совсем уверен, что лучше для моей ситуации. Он действительно не охватывает визуальные компоненты или списки, поэтому – Remi

+1

FMX не налагает ARC. Следующие компиляторы gen используют ARC в качестве управления памятью. На рабочем столе FMX использует то же управление памятью, что и Vcl, т. Е. Право собственности на –

ответ

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; 

Потому что вы делаете, то это установка родителя nil для ARC включен платформы, в результате чего объект Освободившись когда его счетчик ссылок достигает 0 (учитывая, что нет других ссылок на объект, такой как владелец и т. д.).

А на платформах, отличных от ARC, .DisposeOf просто позвоните нам бесплатно. Вы также можете использовать .DisposeOf на платформах ARC, но это оставит ваши объекты в состоянии «Зомби» и не будет «идеальным» решением для управления памятью относительно объектов.

+0

, устанавливающий родительское свойство TFmxObject, просто вызывает метод addObject, так что это не имеет никакого значения. – Remi

+0

@Remi, Да, установка родителя и вызов 'AddObject' сводится к тому же, я просто говорил, что вы также можете сделать это, установив родителя, но мой ответ касается вашего первоначального вопроса об освобождении объектов? –

+0

Почему вы используете ItemByIndex? Почему не MyList.Items или MyList.ListItems? И есть ли у вас документация, подтверждающая ваш ответ? – Remi