Правила работы с ресурсами

Материал из GedeminWiki
Перейти к: навигация, поиск

Блоки динамически выделяемой памяти, дескрипторы файлов, логические кисточки Windows и т.п. все это входит в понятие ресурсы. Экземпляры классов также являются ресурсами, так как, во-первых, создание экземпляра класса всегда сопряжено с выделением блока памяти и, во-вторых, класс сам может использовать (выделять в конструкторе) блоки памяти, файлы, таймеры и т.п. Приложение создает (выделяет) ресурсы по мере необходимости, использует их и затем освобождает. Правильная работа с ресурсами — ключ к построению надежно работающих оптимизированных программ.

Использование конструкции try finally

Если ресурс выделяется, используется и высвобождается в пределах одного блока, то обязательно использование следующей конструкции:

{ allocating resource }
try
  { using resource }
finally
  { free resource }
end;

Это гарантирует, что ресурс будет освобожден даже если при его использовании возникла исключительная ситуация.

Удаление ресурсов в деструкторе класса

Если ресурс создается в конструкторе класса, то он обязательно должен удаляться в деструкторе. Могут не удаляться непосредственно ресурсы, высвобождение которых возлагается на объект владелец (пример: в библиотеке VCL при создании большинства объектов указывается объект владелец (owner), при удалении которого удаляются также и все связанные с ним ресурсы).

constructor MyControl.Create(AnOwner: TComponent);
begin
  inherited Create(AnOwner);
  Timer := TTimer.Create(Self);
  List := TList.Create;
end;
	
destructor MyControl.Destroy;
begin
  List.Free;
  inherited Destroy;
end;

Если ресурс выделяется в одном из методов класса (например, в ответ на некоторое событие), используется и удаляется в других методах, то удаление ресурса обязательно должно дублироваться в деструкторе (с обязательной проверкой на действительность дескриптора ресурса).

procedure WMLButtonDown;
begin
  ...
  { alloc resource }
  ...
end;

procedure WMMouseMove;
begin
  ...
  { use resource }
  ...
end;

procedure WMLButtonUp;
begin
  ...
  { free resource }
  ...
end;
	
destructor Destroy;
begin
  ...
  if Assigned(Resource) then
    { free resource }
  ... 
end;

Ресурсы создаются только по необходимости и удаляются сразу же после окончания их использования. Отсюда следует, что в конструкторе класса создаются только те ресурсы, которые необходимы на протяжении всего времени жизни экземпляра данного класса. Допускается не удалять экземпляры классов, которые необходимы лишь часть времени жизни объекта-владельца и которые могут быть переведены в активное/неактивное состояние (enabled/disabled). Например, таймер можно использовать следующим образом:

constructor MyControl.Create(AnOwner: Tcomponent);
begin
  inherited Create(AnOwner);
  Timer := TTimer.Create;
  Timer.Enabled := False;
  ...
end;

destructor MyControl.Destroy;
begin
  Timer.Free;
  ...
  inherited Destroy;
end;
	
procedure MyControl.WMLButtonDown;
begin
  Timer.Enabled := True;
  ...
end;

procedure MyControl.WMLButtonUp;
begin
  Timer.Enabled := False;
  ...
end;

Delphi по умолчанию создает все формы проекта при запуске приложения. Такой подход неприменим для крупных программ, время запуска которых становится слишком большим, а требования к ресурсам непомерными. Первоначально должна создаваться только одна, главная форма. Все остальные создаются и выводятся на экран по запросу пользователя и удаляются сразу же после окончания использования.

Персональные инструменты
Пространства имён

Варианты
Действия
Навигация
Инструменты