Delphi: 此代码是否是在 FormClose 中使指针归零的正确过程?
Delphi: Is this code a correct procedure of nulling a pointer in FormClose?
IDE: Delphi XE6.
我的主窗体创建了另一个窗体,该窗体创建了 TFormZoom
的实例。一切似乎都完美无缺。
我只是想确保我在 FormClose
中清空指针的过程不会扭曲 Delphi 的一些内部工作原理。
procedure TFormZoom.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
// if I did not set it to nil here, the next time I would create this form I would get
// EAccessViolation, because my other code checks for this form <> nil ...
FormZoom := nil;
end;
我现在在想,这种做法好不好。我没有得到任何编译,也没有 运行-time 错误,这个问题只是一个技术问题。
如果您在 TFormZoom.FormClose
的 end;
处设置断点,并使用 F8 进入调用您的 onclose
事件处理程序的 VCL 代码,您会看到它从 TCustomForm.DoClose
调用,之前从 TCustomForm.Close
调用。在那个时间点,可以看到如下代码(在Delphi10.2.3)
DoClose(CloseAction);
if CloseAction <> caNone then
if Application.MainForm = Self then Application.Terminate
else if CloseAction = caHide then Hide
else if CloseAction = caMinimize then WindowState := wsMinimized
else Release;
因为您将 Action var 设置为 caFree
,这意味着表单的 .Release
将被 VCL 代码调用。我的结论是:将全局变量 FormZoom 设置为 nil,不会造成任何问题。
有时可能根本不会触发 OnClose 事件。所以除了设置
Action := caFree;
我会将其他代码移动到 OnCloseQuery 或 OnDestroy 事件中。
FormZoom := nil;
在我看来, 必须在 OnDestroy 事件中,因为可能还有一些其他事件,例如在控件上,如果表单变量已经为 nil,则在关闭期间会 运行 并导致访问冲突。
IDE: Delphi XE6.
我的主窗体创建了另一个窗体,该窗体创建了 TFormZoom
的实例。一切似乎都完美无缺。
我只是想确保我在 FormClose
中清空指针的过程不会扭曲 Delphi 的一些内部工作原理。
procedure TFormZoom.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
// if I did not set it to nil here, the next time I would create this form I would get
// EAccessViolation, because my other code checks for this form <> nil ...
FormZoom := nil;
end;
我现在在想,这种做法好不好。我没有得到任何编译,也没有 运行-time 错误,这个问题只是一个技术问题。
如果您在 TFormZoom.FormClose
的 end;
处设置断点,并使用 F8 进入调用您的 onclose
事件处理程序的 VCL 代码,您会看到它从 TCustomForm.DoClose
调用,之前从 TCustomForm.Close
调用。在那个时间点,可以看到如下代码(在Delphi10.2.3)
DoClose(CloseAction);
if CloseAction <> caNone then
if Application.MainForm = Self then Application.Terminate
else if CloseAction = caHide then Hide
else if CloseAction = caMinimize then WindowState := wsMinimized
else Release;
因为您将 Action var 设置为 caFree
,这意味着表单的 .Release
将被 VCL 代码调用。我的结论是:将全局变量 FormZoom 设置为 nil,不会造成任何问题。
有时可能根本不会触发 OnClose 事件。所以除了设置
Action := caFree;
我会将其他代码移动到 OnCloseQuery 或 OnDestroy 事件中。
FormZoom := nil;
在我看来,必须在 OnDestroy 事件中,因为可能还有一些其他事件,例如在控件上,如果表单变量已经为 nil,则在关闭期间会 运行 并导致访问冲突。