Как освободить объекты не принадлежащие форме - PullRequest
1 голос
/ 22 сентября 2019

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

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

Посмотрел уже в гугле, но либо нет комментариев по этому поводу, либо я неправильно понял вопрос поиска.

В настоящее время у меня есть:

procedure TmyForm.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
  Registry.Free;
  FileStream.Free;
  MemStream.Free;
end;

Это работает, просто интересно, если это правильный способ сделать это.

1 Ответ

6 голосов
/ 22 сентября 2019

«правильный» способ

Обычно, если форма имеет закрытые поля, которые указывают на объекты, которые вы создаете в обработчике OnCreate (скажем, FormCreate), и что выЕсли вы хотите быть доступным в течение всей жизни формы, вы освобождаете их в обработчике OnDestroy формы (скажем, FormDestroy):

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Registry;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    FRegistry: TRegistry;
    FBitmap: TBitmap;
    FList: TStringList;
  public
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  FRegistry := TRegistry.Create;
  FBitmap := TBitmap.Create;
  FList := TStringList.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FList.Free;
  FBitmap.Free;
  FRegistry.Free;
end;

end.

Таким образом, они будут живы в течение всей жизни вашей формы..

В некоторых случаях вы можете создавать объекты в более позднее время - или даже иметь переменные, указывающие на разные объекты в разное время - но если они принадлежат форме, вы обычно освобождаете их с помощью формыкак в этом примере.(Вспомните, что переменные-члены класса всегда инициализируются, и что вызов Free для переменной nil совершенно безопасен, поскольку Free в основном делает if Assigned then Destroy.)

Почему бы не OnClose?

Использование обработчика OnClose для этого не совсем безопасно, так как он может вызываться несколько раз в течение жизни формы.И если вы введете X.Free, вы получите X, не являющийся nil указателем на мусор.

Например, следующий код является ошибкой:

// BUG!! Don't do this!
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  FList.Free;
  Action := caNone;
end;

Попробуйте дважды закрыть форму.

Даже если вы не используете caNone, возможно, это форма, которая открывается и закрывается несколько раз в течение ее жизни;тогда вы можете не захотеть освобождать все его объекты при первом закрытии.(И вы конечно не хотите освобождать их, не устанавливая указатели на nil!)

Бонусная болтовня

Если вы позволитеВаше поле указывает на разные объекты в разное время, вы должны убедиться, что вы «переопределяете» поле безопасным способом.Например, следующий подход плох:

procedure RecreateFrog;
begin
  FFrog.Free;
  FFrog := TFrog.Create(ftBig, clRed, 123);
end;

Причина в том, что конструктор TFrog.Create может завершиться ошибкой (вызвать исключение), и в этом случае вы получите FFrog не- nil указатель на мусор.Вместо этого более безопасный способ -

procedure RecreateFrog;
begin
  FreeAndNil(FFrog);
  FFrog := TFrog.Create(ftBig, clRed, 123);
end;

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

Конечно, есть другие способы сделать что-то, и иногда у вас есть конструкторычто вы никогда не ошибетесь и т. д. Основное правило заключается в том, что вы должны знать, что вы делаете, и что код должен быть гарантированно никогда не пропускать какие-либо ресурсы, получать доступ к висящим указателям и т. д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...