首页 > 解决方案 > 在另一个表单的 OnDestroy 事件中释放表单时访问冲突

问题描述

我正在使用 Delphi 7。我在释放表单时遇到访问冲突错误。

1) 创建新的应用程序 Delphi 7 (Unit1)

2)添加新表格(Unit2)

3) 对于 Unit1 使用子句添加 Unit2 并编写以下代码

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, unit2, StdCtrls;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
  form2 : TForm2;
begin
  try
    form2 := TForm2.Create(Application);
    //form2.ShowModal;
  finally
    //FreeAndNil(form2);
  end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  if Form2 <> nil then
    FreeAndNil(form2);
end;

end.

4) 运行应用程序并关闭 Form1 -- 出现以下错误。

在此处输入图像描述

我不想在 OnClose 或 OnCloseQuery 上释放 Form2 对象,因为我在这些事件上有一些代码。我想在 OnClose 或 OnCloseQuery 之后释放 Form2 对象。

为什么我收到错误以及如何解决这个问题?

标签: delphidelphi-7

解决方案


您描述的问题可以按照您的步骤在 Delphi 7 中重现。访问冲突的原因是Form2文件中自动创建的(这使应用程序成为表单的所有者.dpr),但您还尝试通过FreeAndNil(Form2)在. 在您尝试释放表单时,应用程序已经释放了它。OnDestroyForm1

目前还不清楚,为什么Form2在应用程序(大概)即将终止(因为主窗体正在被销毁)时尝试释放。由于应用程序是所有者,您可以放心地让应用程序处理其职责。

你需要决定,你想成为谁的所有者Form2

  1. 如果是您,您应该Form2从自动创建的表单列表中删除(请参阅Project - Options - Forms并移至Form2Available forms
  2. 如果您希望应用程序成为所有者,如果需要,只需不要控制其可见性Free的表单、用途hideshow方法,而是将其留给应用程序根据其设计销毁它。

顺便说一句,你里面的代码TForm1.FormCreate()和你看到的 AV 没有任何关系。那Form2是一个单独的实例,如果意图是显示一个splash形式,就可以了,如下:

procedure TForm1.FormCreate(Sender: TObject);
var
  form2 : TForm2;
begin
  form2 := TForm2.Create(nil);
  try
    form2.ShowModal;
  finally
    form2.Free;
  end;
end;

该表单不需要所有者,因此nilCreate. 由于变量form2是本地变量,因此绝对没有必要将其归零。


推荐阅读