если Form.Release вызывается после использования формы, она освобождает всю связанную память, но не устанавливает для переменной формы значение nil.
if not assigned (Form1) then
begin
Application.CreateForm(Tform1, Form1);
try
// Do something
finally
Form1.Release
end;
end;
Чтобы иметь возможность снова вызвать тот же код, Form1 в какой-то момент нужно будет установить в ноль. Из описания Release я не могу
Form1 := nil;
сразу после Release, потому что процедура Release вернется сразу после вызова и до фактического освобождения формы. Я не могу определить, когда Form.Release завершает работу, чтобы установить для формы var значение nil.
Как лучше всего это сделать?





В Delphi Win32 подходящий способ освободить объекты - это вызвать
FreeAndNil(Form1)
Это выполняет обе задачи за один вызов.
Однако у меня такое чувство, что в вашем вопросе есть нечто большее, чем кажется на первый взгляд. Вы используете Delphi для .NET - и если да, то какую версию?
Родди, я использую Delphi Win32 (извините, что не упомянул). Насколько я понял, для формы Release выполняет гораздо больше задач, чем простой FreeAndNil, который не освобождает компоненты, принадлежащие форме. Это верно?
Да, Release делает больше, но только для того, чтобы отложить вызов Free. Вам не нужно называть Free deferred, поэтому вам не нужно вызывать Release, и вы можете вызвать Free. Также см. stackoverflow.com/questions/274523/formrelease-nil#274734
Поставить линию
Form1 := nil;
сразу после звонка в Release.
Release - это просто отправка сообщения CM_RELEASE в форму, что позволяет форме завершить то, что находится в ее очереди (обработчики событий), перед обработкой сообщения CM_RELEASE, что обычно означает просто вызов Free.
Итак, после вызова Release вы не должны предполагать, что переменная Form все еще указывает на действительную форму, таким образом помещая в переменную nil.
Релиз - это просто (потенциально) отложенная бесплатная версия. Первое, что вы должны сделать после вызова Release - это обнулить переменную. Тогда вы будете в безопасности, даже если какой-то код попытается сослаться на Form1 до того, как он будет уничтожен. В случае, как в вашем коде, он просто безопасно воссоздает другой Form1 для нового использования, не беспокоясь о том, что тот уничтожается.
Как уже упоминалось, Release - это только отложенное Free для формы, которую можно использовать, если она хочет закрыть / освободить саму себя. Если не считать отсрочки, он ничем не отличается от Release. Таким образом, в этом примере нет смысла вызывать Release. Звонить бесплатно кажется более логичным. И вы можете установить его равным нулю после вызова Free или использования FreeAndNil.
Если вы все еще хотите использовать Release, это нормально. Просто установка значения переменной на nil работает. Это не заставляет форум вести себя иначе. Но помните, что в этом случае более эффективным и детерминированным будет вызов Free вместо Release. Я предпочитаю использовать Release только там, где это действительно необходимо.
Вы всегда могли назвать это:
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;
Обязательно проверьте тип после преобразования в TObject, так как вы не можете проверить тип Obj. Этот должен будет безопасным, поскольку, как и Free, Release не является виртуальным.
связанные: stackoverflow.com/questions/916843/…