Вопрос, поднятый пользователем, касается правильности процедуры обнуления указателя на форму в событии FormClose в среде разработки Delphi XE6. Разработчик создаёт форму TFormZoom внутри основной формы, и для предотвращения ошибки доступа после закрытия формы (EAccessViolation) пытается обнулить указатель на форму в методе FormClose. В коде используется глобальная переменная FormZoom, которая обнуляется для предотвращения ошибок при последующем создании формы.
procedure TFormZoom.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
FormZoom := nil;
end;
Анализ проблемы
Пользователь спрашивает, является ли данный подход корректным, несмотря на отсутствие компиляционных и runtime-ошибок. Вопрос носит технический характер и связан с пониманием внутреннего механизма работы Delphi.
Альтернативный ответ
В комментариях к вопросу предложено избегать использования глобальных переменных, сгенерированных IDE Delphi, и рекомендуется удалять их в секции глобальных переменных, если форма использует другую форму. Также предлагается определять переменную внутри класса формы.
Подтвержденный ответ
Для подтверждения корректности подхода пользователя был проведён анализ кода, вызывающего событие FormClose. В Delphi 10.2.3 видно, что после установки переменной Action в значение caFree, вызывается метод Release формы. Это означает, что обнуление глобальной переменной FormZoom не вызовет проблем, так как форма уже освобождена внутренними механизмами Delphi.
Рекомендации
Избегайте использования глобальных переменных, сгенерированных IDE, и предпочитайте их определение внутри класса формы.
Убедитесь, что после установки Action в caFree, форма будет корректно освобождена, что подтверждается анализом внутреннего кода Delphi.
Пример кода
type
TMyForm = class(TForm)
private
{ Déclarations des champs, de l’instruction privée }
FZoomForm: TFormZoom;
public
{ Déclarations des propriétés publiques }
property ZoomForm: TFormZoom read FZoomForm write FZoomForm;
{ Déclarations de l’instruction publique }
end;
procedure TMyForm.ShowZoomForm;
begin
if FZoomForm is nil then
FZoomForm := TFormZoom.Create(nil);
try
FZoomForm.Show;
finally
// Не нужно обнулять указатель в finally блоке, это сделает Delphi автоматически
end;
end;
Заключение
Использование глобальных переменных для хранения указателей на формы в Delphi может привести к ошибкам, если не соблюдать осторожность. Обнуление указателя в методе FormClose после установки Action в caFree является корректным действием, но лучше предпочесть использование свойств класса формы для управления жизненным циклом форм, что позволит избежать потенциальных проблем с доступом после освобождения формы.
Вопрос касается правильной установки указателя в NULL для формы TFormZoom в событии FormClose в Delphi XE6 для предотвращения ошибки EAccessViolation после закрытия формы.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS