Вопрос
если после использования формы вызывается Form.Release, он освобождает всю связанную память, но не устанавливает для переменной формы значение nil.
if not assigned (Form1) then
begin
Application.CreateForm(Tform1, Form1);
try
// Do something
finally
Form1.Release
end;
end;
Чтобы снова вызывать тот же код, в какой-то момент для Form1 должно быть установлено значение nil. Из описания релиза я не могу сделать
Form1 := nil;
сразу после Release, поскольку процедура Release будет возвращаться сразу после вызова и до того, как форма будет фактически освобождена. Я не могу определить, когда завершается Form.Release, чтобы установить для формы var значение nil.
Каков наилучший способ сделать это?
Решение
Поместите строку
Form1 := nil;
сразу после звонка в Release.
Release просто отправляет сообщение CM_RELEASE в форму, что позволяет форме завершать то, что находится в ее очереди (обработчики событий), до обработки сообщения CM_RELEASE, что обычно означает просто вызов Free.
Таким образом, после вызова Release не следует предполагать, что переменная Form все еще указывает на допустимую форму, тем самым помещая nil в переменную.
Другие советы
Релиз - это просто (потенциально) отложенный бесплатный. Первое, что вы должны сделать после вызова Release, - обнулить переменную.
Тогда вы будете в безопасности, даже если какой-то код попытается обратиться к Form1 до того, как он будет фактически уничтожен. В случае, как в вашем коде, он просто безопасно воссоздает другую форму Form1 для нового использования, не беспокоясь об уничтожаемой.
Из вас всегда можно было так назвать:
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 не является виртуальным. Р>
Как уже упоминалось, Release является только отложенным Free для формы, которую можно использовать, если она хочет закрыть / освободить себя. Кроме того, отсрочка не отличается от Release. Таким образом, нет смысла вызывать Release в этом примере. Вызов Free кажется более логичным. И вы можете установить его на ноль после вызова Free или использовать FreeAndNil. Р>
Если вы все еще хотите использовать Release, это нормально. Просто установка значения переменной на ноль работает. Это не заставляет форум вести себя по-другому. Но помните, что в этом случае более эффективно и более детерминировано называть Free вместо Release. Я предпочитаю использовать Release только там, где это действительно необходимо.
В Delphi Win32 подходящим способом освобождения объектов является вызов
FreeAndNil(Form1)
Это выполняет обе работы за один вызов.
Тем не менее, у меня есть подлое ощущение, что в твоем вопросе есть нечто большее, чем кажется на первый взгляд. Используете ли вы Delphi для .NET - и если да, то какая версия?