我正在使用Delphi 7.我在释放表单时遇到访问冲突错误。
1)创建新的Application Delphi 7(Unit1)
2)添加新表格(单元2)
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对象。
为什么我会收到错误以及如何解决此问题?
答案 0 :(得分:4)
您描述的问题可以按照您的步骤在Delphi 7中重现。访问冲突的原因是Form2
在.dpr
文件中自动处理(这使得应用程序成为表单的所有者),但您也尝试通过调用{{1}来控制其生命周期FreeAndNil(Form2)
OnDestroy
事件中的Form1
事件。在您尝试释放表单时,它已被应用程序释放。
当应用程序(可能)即将终止(因为主要表单被销毁)时,为什么你试图释放Form2
并不是很清楚。由于应用程序是所有者,您可以安全地让应用程序负责其职责。
您需要决定,您希望成为Form2
的所有者。
Form2
(请参阅Project - Options - Forms
并将Form2
移至Available forms
)。Free
表单,如果需要,可以使用hide
和show
方法来控制其可见性,但请将其保留应用程序根据其设计销毁它。顺便说一下,TForm1.FormCreate()
中的代码与您看到的AV无关。那个Form2
是一个单独的实例,如果打算显示一个启动形式,那就没关系,如下所示:
procedure TForm1.FormCreate(Sender: TObject);
var
form2 : TForm2;
begin
form2 := TForm2.Create(nil);
try
form2.ShowModal;
finally
form2.Free;
end;
end;
表单不需要所有者,因此nil
中的Create
。由于变量form2
是本地的,因此绝对没有必要将它变为零。
答案 1 :(得分:3)
问题是Form2
将在unit2
中声明,并再次在此表单的FormCreate中声明。你只是使用了错误的。
我建议从unit2中删除Form2
的声明,只使用本单元中的声明,并将声明移到私有部分
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
Form2: TForm2; // Declare the form here, not in unit2
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
Form2 := TForm2.Create(nil);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
// no need to check if Form2 exists, it is created in the FormCreate and will thus always exist
// unless there is code somewhere that we cant see that destroys it.
// Also no need to set the variable to nil as mentioned in the Tom's answer
Form2.Free;
end;