Form.Release + NIL - PullRequest
       11

Form.Release + NIL

11 голосов
/ 08 ноября 2008

если вызывается Form.Release после использования формы, он освобождает всю связанную память, но не устанавливает для переменной формы значение nil.

if not assigned (Form1) then
  begin
    Application.CreateForm(Tform1, Form1);
    try
      // Do something
    finally
      Form1.Release
    end;
  end;

Чтобы снова вызвать тот же код, в какой-то момент Form1 должен быть установлен в ноль. Из описания релиза не могу сделать

Form1 := nil;

сразу после Release, потому что процедура Release будет возвращаться сразу после вызова и до того, как форма будет фактически освобождена. Я не могу определить, когда завершается Form.Release, чтобы задать для формы var значение nil.

Каков наилучший способ сделать это?

Ответы [ 5 ]

16 голосов
/ 08 ноября 2008

поставить строку

  Form1 := nil;  

сразу после звонка в Release.

Релиз - это просто отправка сообщения CM_RELEASE в форму, что позволяет форме завершить то, что находится в ее очереди (обработчики событий), до обработки сообщения CM_RELEASE, что обычно означает просто вызов Free. Таким образом, после вызова Release вы не должны предполагать, что переменная Form все еще указывает на допустимую форму, таким образом помещая nil в переменную.

11 голосов
/ 08 ноября 2008

Релиз - это просто (потенциально) отсроченный бесплатный. Первое, что вы должны сделать после вызова Release, - обнулить переменную.
Тогда вы будете в безопасности, даже если какой-то код попытается обратиться к Form1 до того, как он будет фактически уничтожен. В случае, подобном вашему коду, он просто безопасно воссоздает другую форму Form1 для нового использования, не беспокоясь о том, что он уничтожен.

4 голосов
/ 08 ноября 2008

Из вас всегда можно было бы назвать это:

procedure FreeOrReleaseAndNil(var Obj);
var
  Temp: TObject;
begin
  Temp := TObject(Obj);
  Pointer(Obj) := nil;
  if Temp is TCustomForm then
    TCustomForm(Temp).Release
  else
    Temp.Free;
end;

Обязательно проверьте тип после приведения к объекту TO, поскольку вы не можете проверить тип Obj. Это должно быть безопасным, поскольку, как и Free, Release не является виртуальным

2 голосов
/ 08 ноября 2008

Как уже упоминалось, выпуск является только отложенным бесплатным для формы, которую он может использовать, если он хочет закрыть / освободить себя. Кроме того, отсрочка не отличается от Release. Таким образом, нет смысла вызывать Release в этом примере. Вызов Free кажется более логичным. И вы можете установить его на ноль после вызова Free или использовать FreeAndNil.

Если вы все еще хотите использовать Release, это нормально. Просто установка значения переменной на ноль работает. Это не заставляет форум вести себя по-другому. Но помните, что в этом случае более эффективно и более детерминировано называть Free вместо Release. Я предпочитаю использовать Release только там, где это действительно необходимо.

0 голосов
/ 08 ноября 2008

В Delphi Win32 подходящим способом освобождения объектов является вызов

FreeAndNil(Form1)

Это выполняет обе работы в одном вызове.

Тем не менее, у меня есть подлое чувство, что в вашем вопросе есть нечто большее, чем кажется на первый взгляд. Используете ли вы Delphi для .NET - и если да, то какая версия?

...