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.FormCloseend; 处设置断点,并使用 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,则在关闭期间会 运行 并导致访问冲突。