TStrings и освобождение объектов

Проблема: Компоненты, которые имеют поле Items: TStrings могут содержать как просто текстовую ифнорацию, так и объекты (TObject). Такими компонентами являются TListBox, TCheckListBox, TComboBox…
Объекты, добавленные в TStrings даже после уничтожения экземпляра класса, остаются не уничтоженными, потому они должны быть явно уничтожены. Если вы об этом не позаботитесь в результате получите утечки памяти. (Как отобразить утечки памяти можно помсотреть в статье: Delphi отображение утички памяти)
Решение: Можно воспользоватьсь обобщенной процедурой, которая будет удалять объекты которые находятся в TStrings.

...
uses
  SysUtils; //Для использования FreeAndNil
...
procedure FreeObjects(const AStrings: TStrings);
var
  I : Integer;
  Obj: TObject;
begin
  for I := 0 to Pred(AStrings.Count) do
  begin
    Obj := AStrings.Objects[I];
    if Assigned(Obj) then
      FreeAndNil(Obj);
    end;
end;

Использование: Для использования нужно передать свойство Items соответствующего компонента.

FreeObjects(ListBox1.Items);
FreeObjects(TCheckListBox.Items);
FreeObjects(ComboBox1.Items);

Пример: Для демонстрации описанного, я создал тестовый проект, который можно скачать и посмотреть на GitHub. (При написании проекта использовал Delphi XE4).
Описание проекта: Есть форма с двумя кнопками (Рис. 1). При нажатии на кнопку, добавляется в соответствующий список запись (в формате № п/п записи) (Рис. 2). Данные в список добавляются с помощью самописной процедуры AddObject. На событие формы onDestroy идет вызов процедуры FreeObjects, при этом освобождаются объекты только одного списка(TComboBox).

FreeObject1

Рис.1 Демо программа

FreeObject2

Рис. 2 Добавление элементов в список

Если закрыть программу в данный момент, тогда мы получим сообщение об утечке памяти Рис. 3

FreeObject3

Рис. 3 Утечка памяти

Все правильно, поскольку объекты в списке нумеруются с «0», то у нас было создано 5 объектов, и не уничтожены. Два объекта также были созданы в первом списке и были удалены при закрытии программы.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *