Как правильно уничтожить форму в Delphi? - PullRequest
3 голосов
/ 27 мая 2020

Я оставил только основную форму в автоматически создаваемых формах, а остальные удалил. Обычно я вызываю эти формы с помощью

TMyForm.Create(Self).Show;

. Но когда мои работы выполнены с помощью этой формы, как я могу освободить ресурсы, которые эта форма использовала наилучшим образом? Я просмотрел функции Free, Action.CaFree, Destroy, FreeAndNil, но не могу получить их все.

Я ищу лучшие практики.

Спасибо.

Ответы [ 2 ]

12 голосов
/ 27 мая 2020

Это полностью зависит от того, как используется форма.

Модальные формы

Самый простой случай - это модальная форма. Затем вы обычно используете следующую идиому:

procedure TForm1.btnFrogPropertiesClick(Sender: TObject);
var
  Frm: TFrogPropertiesForm;
begin
  Frm := TFrogPropertiesForm.Create(Self);
  try
    Frm.ShowModal;
  finally
    Frm.Free;
  end;
end;

Или, если вы хотите выполнить некоторую специальную обработку, если пользователь закрывает диалоговое окно, нажав кнопку OK (а не Отмена * кнопка 1011 *):

procedure TForm1.btnFrogPropertiesClick(Sender: TObject);
var
  Frm: TFrogPropertiesForm;
begin
  Frm := TFrogPropertiesForm.Create(Self);
  try
    if Frm.ShowModal = mrOk then
      UpdateFrog;
  finally
    Frm.Free;
  end;
end;

Обратите внимание, что я использую Self как владелец в обоих случаях. В этом нет необходимости ради владения, поскольку - совершенно очевидно - мы освобождаем формы, как только они закрываются. Но я все равно часто использую Self, потому что я обычно использую Position = poOwnerFormCenter для своих диалогов.

Независимые windows, которые освобождаются, когда вы их закрываете

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

procedure TForm1.Button1Click(Sender: TObject);
var
  ImageViewer: TImageViewerFrm;
begin
  ImageViewer := TImageViewerFrm.Create(nil);
  ImageViewer.Image := 'flower.jpg';
  ImageViewer.Show;
end;

при условии, что у него есть свойство publi c с именем Image, которое принимает имя файла изображения для отображения.

Это будет создать и показать форму при нажатии на кнопку. Чтобы убедиться, что он освобожден, когда вы его закроете, просто добавьте обработчик OnClose к TImageViewerFrm и установите для параметра Action значение caFree:

procedure TImageViewerFrm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
end;

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

Другие подходы

Конечно, есть еще много возможных сценариев ios, а значит, и многих других возможных решений. В некоторых случаях вам может потребоваться полный контроль над формами определенного типа, поэтому вы храните их в массиве. Это нормально, чтобы освободить их, используя MyForm.Free или FreeAndNil(ImageForms[4]).

FreeAndNil(X) эффективно выполняет X.Free; X := nil (но более безопасным способом), то есть после него устанавливается значение nil. освободил объект, на который он указывал. Таким образом вы избежите зависшего указателя. В некоторых случаях это необходимо. (Но теперь я отвлекся. Это относится к Delphi объектам в целом и не имеет ничего общего с формами в частности.)

Но в Delphi вы никогда не освобождаете объект (форма или нет) написав X.Destroy. Вы используете X.Free, который эффективно выполняет if X <> nil then X.Destroy.

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

0 голосов
/ 29 мая 2020

, если вы создаете форму и хотите, чтобы она освободилась после закрытия, тогда в событии ONCLOSE напишите action := cafree;

таким образом вам не придется использовать TRY ... освободи его.

...