我正在使用 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 对象。
为什么会出现错误以及如何解决?
最佳答案
按照您的步骤,您描述的问题可以在 Delphi 7 中重现。访问冲突的原因是 Form2
是在 .dpr
文件中自动创建的(这使应用程序成为表单的所有者),但您还试图控制它通过在 Form1
的 OnDestroy
事件中调用 FreeAndNil(Form2)
来延长生命周期。在您尝试释放表单时,它已被应用程序释放。
目前还不是很清楚,为什么当应用程序(大概)即将终止(因为主窗体正在被销毁)时您试图释放 Form2
。由于应用程序是所有者,您可以安全地让应用程序处理它的职责。
您需要决定,您希望谁成为 Form2
的所有者。
- 如果是你,你应该从自动创建的表单列表中删除
Form2
(参见Project - Options - Forms
并移动Form2
至可用表格
)。 - 如果您希望应用程序成为所有者,只需不要
Free
表单,使用hide
和show
方法来控制它可见性(如果需要),但将其留给应用程序根据其设计销毁它。
顺便说一下,您在TForm1.FormCreate()
中的代码与您看到的AV 无关。那个Form2
是一个单独的实例,如果意图是展示一个splash form,也可以,如下:
procedure TForm1.FormCreate(Sender: TObject);
var
form2 : TForm2;
begin
form2 := TForm2.Create(nil);
try
form2.ShowModal;
finally
form2.Free;
end;
end;
表单不需要所有者,因此 Create
中的 nil
。由于变量 form2
是本地变量,因此绝对没有必要将其设为 nil。
关于delphi - 在另一个窗体的 OnDestroy 事件中释放窗体时发生访问冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50004757/