关于资源释放的问题!(在线等待,up有分,希望大家指教)(200分)

T

ty_unix

Unregistered / Unconfirmed
GUEST, unregistred user!
程序如下:
program Project1;

uses
Forms,
Unit1 in 'Unit1.pas' {Form1},
Unit2 in 'Unit2.pas' {Form2},
Unit3 in 'Unit3.pas' {Form3};

{$R *.RES}

begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.

unit Unit1;

interface

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

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

var
Form1: TForm1;

implementation

uses Unit2;

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
begin
if Form2=nil then
Form2:=TForm2.Create(self);
Form2.show;
end;

end.

unit Unit2;

interface

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

type
TForm2 = class(TForm)
Button1: TButton;
ComboBox1: TComboBox;//可以不要
ComboBox2: TComboBox;
ComboBox3: TComboBox;
ComboBox4: TComboBox;
ComboBox5: TComboBox;
ComboBox6: TComboBox;
ComboBox7: TComboBox;
ComboBox8: TComboBox;
ComboBox9: TComboBox;//可以不要
ComboBox10: TComboBox;//可以不要
ComboBox11: TComboBox;//可以不要
ComboBox12: TComboBox;//可以不要
ComboBox13: TComboBox;//可以不要
ComboBox14: TComboBox;//可以不要
ComboBox15: TComboBox;//可以不要
ComboBox16: TComboBox;//可以不要
ComboBox17: TComboBox;//可以不要
ComboBox18: TComboBox;//可以不要
ComboBox19: TComboBox;//可以不要
ComboBox20: TComboBox;//可以不要
ComboBox21: TComboBox;//可以不要
procedure Button1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form2: TForm2;

implementation

uses Unit3;

{$R *.DFM}

procedure TForm2.Button1Click(Sender: TObject);
begin
if Form3=nil then
Form3:=TForm3.Create(nil);
Form3.show;

close;
//FreeAndNil(Self);
end;

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
free;//或者用action:=cafree;
end;

end.

unit Unit3;

interface

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

type
TForm3 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form3: TForm3;

implementation

uses Unit2;

{$R *.DFM}

procedure TForm3.Button1Click(Sender: TObject);
begin
if form2=nil then
Form2:=TForm2.Create(nil);
form2.show;
close;
//FreeAndNil(Self);
end;
procedure TForm3.FormClose(Sender: TObject; var Action: TCloseAction);
begin
free; //或用action:=free;
end;

end.

Button1Click按下这个按钮提示错误
错误提示,access violation at address 6D6F4354.read of address 6D6F454

希望各位指教
 
你的form2、form3是不是MDI子窗体呢?不是的话在onclose里面加free干嘛呢?
 
to HunterTeam

不是子窗体难道不能free吗?难道一定要字窗体才能free吗?希望详解。
 
不是子窗体是不需要Free的。如果在MDI主窗体中打开子窗体,不在onclose中加action:=caFree
的话,子窗体在关闭时只会最小化而不会退出。
一般的,非自动创建的非子窗体,可以按如下语句调用并在调用后释放:
form2:=Tform2.Create(self);
form2.showmodal;
form2.free;
 
另外,要想在非子窗体的onclose里FREE也是可以的,但要在action:=cafree(注意不要用free)
后再加一句form2:=nil之类的,因为free并不能所form2置为nil,很多对象在释放时也都是这样的,
因为free不会自动将对象置为nil,所以在调用free之后,最好是再手动将对象置为nil。
你的那句错误就出在form已被free掉,但并不为nil,而你在buttonclick中试图调用已被
free的form2,当然就会出错了。
 
最好是在OnDestroy里面Form2 := nil吧。
 
你将form2与form3的onclose都去掉,或者将其中的free改为formX:=nil;也可以.按你的程序
看采用第一种比较好,因为form2与form3都不是主窗口,所以使用close后,并没有释放,只是隐
藏了起来,相当于使用hide方法,所以这时不用再建立就可以使用show方法显示出来,这样就与你
的程序流程相一致了.
 
to HunterTeam
谢谢你的指教,我是想free一个窗体后然后再次建立这个窗体,而且是必须把本窗体的
资源释放出来,然后当下次调用的时候再建立,有什么更好的方法吗?

上面哪个程序的问题可以这样解决,不会报错。

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
// free;
Action:=caFree;
Form2:=nil;
end;

procedure TForm2.Button1Click(Sender: TObject);
begin
if Form3=nil then
// Form3:=TForm3.Create(self);
Form3:=TForm3.Create(nil);
// Form3.show;
Form3.ShowModal;

close;
end;

procedure TForm3.Button1Click(Sender: TObject);
begin
if form2=nil then
Form2:=TForm2.Create(self);
form2.show;

close;
end;
procedure TForm3.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:=caFree;
Form3:=nil;
end;
 
这样就可以了嘛,form2buttonclick中注释掉的那两句也可以用,不会报错。
 
to HunterTeam
能给一种跟好的方法吗?因为我的几个窗体上放的控件太多,大概有200个左右,
如果不释放资源,那将无法运行,我只有在用一个后释放一个,但是这几个窗体可能会
重复调用,用上面的方法也试过了,但还是无法根本解决。还会出现资源不够的现象
 
在给两200分,谁能给一个好的方法,??
 
将你的三个form同时打开如果不出现资源不足的话,你就不要再使用这种释放后再建立的方法了,
因为这样总是难免会出现内存碎片.并且你form上控件很多,也保不定哪个会出错.
就用hide,不用的时候就hide,用的时候再show不就可以了吗?这样只要建立一次,以后就不必再
释放再建立了.这样必免了内存碎片的产生.
按这个思路试试看[:)]
 
我一直是这样用的,没问题:
procedure TForm3.Button1Click(Sender: TObject);
begin
if not assigned(Form2) then
Form2:=TForm2.Create(Application);
Form2.ShowModal;
Form2.Free;
Form2:=nil;
end;
 
多人接受答案了。
 
顶部