向概念清楚的高手请教 (100分)

  • 主题发起人 主题发起人 kntrue
  • 开始时间 开始时间
K

kntrue

Unregistered / Unconfirmed
GUEST, unregistred user!
我在做一个登录窗体是遇到一下问题,当我点击form2上的按钮时,让form1弹出,form1是主窗体
但是在释放form2内存时,遇到了问题,请问下面的这几种情况那种是对的,不对的为什么?
我得form2是在project option 中设置为availale forms.

1:-----
unit1
var
Form1: TForm1;

implementation
uses unit2;
{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
form2:=Tform2.Create(self);
form2.ShowModal;
end;
unit2:
var
Form2: TForm2;

implementation
uses unit1;
{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
begin
form2.Close;
form1.Show;

end;

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
action:=caFree;
form2:=nil;
end;
注:这个方法可以实现,用2000的任务管理器查看内存确实释放了,但是下面这个用form2.free却不行了???
2:------
unit1
var
Form1: TForm1;

implementation
uses unit2;
{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
form2:=Tform2.Create(self);
form2.ShowModal;
end;

unit2
var
Form2: TForm2;

implementation
uses unit1;
{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
begin
form2.Close;
form1.Show;
end;

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
form2.Free;
form2:=nil;
end;
注:这种情况不行,会抛异常,用2000的任务管理器查看内存没有释放,真是想不通只是用了个form2.free就不行为什么???
当运行时点下button时会出现'access violation at address 00010001。write of address 01965D34'

3:可是在这种情况下用form2.free又对了,真的不解!!!
unit1
var
Form1: TForm1;

implementation
uses unit2;
{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
frm : TForm2;
begin
frm := TForm2.Create(self);
frm.ShowModal;
frm.Free;
frm:= nil;
end;

unit2:
var
Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
begin
close;
end;

我真的快被这个问题搞疯了,请高手解释,谢谢,谢谢
 
在delphi中说的很清楚,一般不是主form的在使用close方法后,它只是不在显示,但它并没有
从内存中释放,这时只要再调用show方法就可再次显示出来而不需要再次建立.所以上面第三
种方法就可以理解了.在第一种方法中,你将action设为了caFree,看一下帮助就可以知道,这时
delphi是就会将其从内存中释放掉了.第二种方法关系到在FROM关闭时各种事件产生的顺序.在网
上有很多这方面的文章你可以查看.当你调用free时,将会产生formclose事件,如果你再在该事
件中调用同一个form的free方法,可以想象会产生什么后果.[:)]
以上是我的一点观点,不对的地方请大家指教.
 
你看看Form在Close时候做了什么就知道为什么了:
...
DoClose(CloseAction); //这里执行你的OnClose代码
//如果你在OnCLose把From给Free掉了,由于CloseAction的默认企是caHide
//所以执行下面的代码的时候就出错了。
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;
end;
当然,你可能想到,在FormClose时候把CloseAction 设成caNone是不是就没事了?
对,这样是不会报内存访问错误,但会造成你的应用程序出问题了
另外,如果你的form2是主窗口的情况下,又不会报错,因为这时执行的是
if Application.MainForm = Self then Application.Terminate
 
procedure TForm1.FormCreate(Sender: TObject);
begin
form2:=Tform2.Create(self);
form2.ShowModal;
end;
我看到这儿就不想看了,到底哪个是主窗口?
 
对不起,我没说清楚,form1是主窗口。
xianjun老兄,那请你告诉我为什么,的三种情况可以??
windbell兄,按你的说法我把第二种情况改成了
2:
var
Form2: TForm2;

implementation
uses unit1;
{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
begin
//form2.Close;
form1.Show;
form2.Free;
form2:=nil;
end;
的确编译不会报错,但是当我关闭产生的form1(主窗口)时,.exe程序没有结束,仍然驻留在
任务管理器中,但第1,第2种方案不会出现这种情况

感谢所有答复我得大虾!!

 
我查过很多类似的帖子,很多人说释放内存就是在窗体的close事件中,free他。但现在说明
这样不行,我想这是一个概念问题,请高手们别嫌他简单,给小弟解释解释,我一旦搞懂马上
给分,谢谢,谢谢
 
第三种情况当然可以了,因为你不是在Form自己的事件中Free

>>很多人说释放内存就是在窗体的close事件中,free他
那是说的别的自己分配的内存,而不是窗体自己,窗体自己要想释放,只要在OnClose
事件中把CloseAction 设成caFree就行了。
或者用其他的写法,如第三种
 
谢谢诸位,特别是xianjun,我懂了,现在就散分!!
 
后退
顶部