动态创建的窗体 如何 释放??

时间:2023-01-15 23:47:16
一、///////// 在FrmMain中动态创建Frm2窗体
procedure TFrmMain.***(***); 
 begin

Frm2:=TFrm2.Create(application);

with frm2 do
begin
//.........
end

if 某种错误 then
frm2.free;  // 就是不要Frm2显示出来,这样释放对吗?要再用Destroy吗?
else        // 如果没错则将Frm2显示出来
Frm2.Show;
self.Hide;
end;

////////////////////Frm2的CLose中Destroy
procedure TFrm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  FrmMain.Show;
  self.Destroy;
end;

这样对吗? 要先Frm2.Free吗?


二、///////// 另外一种以模态框形式显示出来

procedure ShowForm(FormClass: TFormClass):integer;
begin
  With FormClass.Create(Application) do
 try
     ShowModal;
  finally
    Free;         // 这个不明白,finally后面跟的是不是不管Try部分
  end;
result:=**
end;

 // Free;        
 // 这个不明白,finally后面跟的是不是不管Try部分是否正常执行,都会运行?
那如果不管Try对否都运行Free部分的话,那result:=** 不是都不会执行了吗?
还是我Free理解有错,Free跟Destroy到底啥区别?

谢谢

24 个解决方案

#1


你Create(self)或Create(Application)后,其实自己不用管释放的~
我记得时这样的吧!

#2


在free过程中会隐式调用Destroy 
procedure TObject.Free;
begin
  if Self <> nil then
    Destroy;
end; 

finally后面跟的不管Try部分是否正常执行,都会运行.

#3


try
finally
end;
就算在try中出现异常,finally里的代码都会执行。
所以在try里绝对不能free;

至于你的result这句肯定会执行的,只要你不访问前面一个form里的东西。

#4


finally后面跟的不管Try部分是否正常执行,都会运行

在free过程中会隐式调用Destroy 
procedure TObject.Free;
begin
  if Self <> nil then
    Destroy;
end;

#5


慢慢,就会明白的!
打了这么多字才发现要想把上面的问题都说清楚,不容易啊!

其实里面都是简单的问题,多看看书,多写写程序,就知道的了~~~

#6


自己顶一下
没人回~~

#7


原来有人回,是我没刷新 呵呵

你Create(self)或Create(Application)后,其实自己不用管释放的~
我记得时这样的吧!

== 
try
     ShowModal;
  finally
    Free;   
那为什么这里还要Free?

procedure TFrm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  FrmMain.Show;
  self.Destroy;
end;
那就是说是不是不用 在Close时加这句 self.Destroy; ??

越来越不明白了。。

是不是动态创建以后,就不用管它了,不用去Destroy,也不用去Free??
那下回再用到那个窗体是不是直接Show就好了? 它还在吗?



#8


FreeAndNil(MyForm);

#9


打开project-> options->forms看看你的form是在auto-create forms还是在available forms
如果在auto-create forms那么在project->viewsource看到  Application.CreateForm(TForm1, Form1);这是自动创建了;如果available forms那你需要动态创建
try
  fm1 := Tform1.Create(nil);
  showmodal;
finally
  FreeAndnil(fm1);
end;

#10


那如果不是 ShowModal的话

如果Frm1,frm2都要用到动态创建的Frm3

那比如在Frm1里先动态Create Frm3,再Frm3.show --先不在Frm1里释放

而然后Frm2要用到的话,直接就Frm3.show,用完后再FreeAndNil(frm3)

这样行吗?

#11


...
try
  Application.CreateForm(TFrmTemp,FrmTemp);
  FrmTemp.ShowModal;
finally
  FreeAndNil(FrmTemp);
end;

#12


一个动态创建的Frm在Close之后,下回再Show要不要再次Create动态创建?

像Close,Destroy有什么不一样? 我怎么感觉都一样

#13


1、下次要不要再次创建要看你这个窗体对象的生存周期,基本概念
2、Close是关闭窗体,就是不显示了(隐藏了),但是这个对象还在,下次你可以调用Show再显示(前提如1),Destroy是释放窗体对象,释放了就不能再Show了,Free功能与Destroy基本相同,但是它会先检测一下自己是不是空指针,不是才会调用Destroy;
3、一般情况下使用Free

#14


我做了个测试:
procedure TForm1.Button1Click(Sender: TObject);
begin
    if form2=nil then
    begin
      showMessage('frm2 is nil now');
      form2:=Tform2.Create(application);
      try
        form2.ShowModal;
        finally
        //freeandNil(form2);   // freeAndNil 以后才可以再按下Btn
       form2.Free;      // 若是Free则再次按Btn会出错。。
      end; //try
end; //proc

procedure TForm1.Button2Click(Sender: TObject);
begin
 if form2=nil then
        showMessage('frm2 is nil after free')
      else
        begin
         showMessage('frm2 is not nil after free');
        form2.ShowModal;
         end;

end;


1.按下Form1的Btn1,模态显示Form2
2.按Form2的Cancel按钮关闭
3.按下From1的Btn2
结果: 若Btn1Click的程序中用的是 Finally form2.Free;   则到第3步会出错,显示完“'frm2 is not nil after free'”后,就出错了

而若  若Btn1Click的程序中用的是 Finally FreeAndNil(form2),则第3步显示完 'frm2 is nil after free'后,还可以再显示Form2

我不明白了: 不是说Free就是把窗口释放了吗?为什么还不是为成Nil? 那FreeAndNil和Free又差在哪了?

Free功能与Destroy基本相同,但是它会先检测一下自己是不是空指针,不是才会调用Destroy;
==Free不能把窗口变成Nil啊?

#15


还有个非模态框怎么释放自己?

就是在Frm1中Create了Frm2,再Frm2.show

现在要Frm2关闭的时候自己释放自己
我这样写:
procedure TFrm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
//  freeAndNil(self);
self.destroy;
end;

两个都不行,Free应该也不行

那要怎么自己将自己Nil掉?

#16


self.release;

#17


Free就是单纯释放,并没有将其置成空(nil);FreeAndNil是释放并置为空

#18


mark

#19


引用别处“实例就是类在内存里面的对象,占用两个部分的内存空间:一个是栈里面的对象指针空间,另外一个就是堆里面的对象实例空间,
两个部分应该是对应的,所以释放的时候要主要不要只释放了堆里面的对象实例空间而不释放栈中的指针空间....  
 
例如在将一个窗体释放的时候,不应该只将对象释放,如Self.Free  
 
而同时应该将指针进行释放,所以需要使用FreeAndNil(Self)这个句子”

#20


谢谢上面所有回的


procedure ShowForm(FormClass: TFormClass):integer;
begin
  With FormClass.Create(Application) do
 try
     ShowModal;
  finally
    Free;         // 这个不明白,finally后面跟的是不是不管Try部分
  end;
result:=**
end;

那怎么上面这段程序这么流行, 我看书里都这样
都没再Nil的,真奇怪。。


#21


mark

#22


destroy的方法就是判断是否为nil 不是就free

#23


self.destroy

#24


action:=caFree

#1


你Create(self)或Create(Application)后,其实自己不用管释放的~
我记得时这样的吧!

#2


在free过程中会隐式调用Destroy 
procedure TObject.Free;
begin
  if Self <> nil then
    Destroy;
end; 

finally后面跟的不管Try部分是否正常执行,都会运行.

#3


try
finally
end;
就算在try中出现异常,finally里的代码都会执行。
所以在try里绝对不能free;

至于你的result这句肯定会执行的,只要你不访问前面一个form里的东西。

#4


finally后面跟的不管Try部分是否正常执行,都会运行

在free过程中会隐式调用Destroy 
procedure TObject.Free;
begin
  if Self <> nil then
    Destroy;
end;

#5


慢慢,就会明白的!
打了这么多字才发现要想把上面的问题都说清楚,不容易啊!

其实里面都是简单的问题,多看看书,多写写程序,就知道的了~~~

#6


自己顶一下
没人回~~

#7


原来有人回,是我没刷新 呵呵

你Create(self)或Create(Application)后,其实自己不用管释放的~
我记得时这样的吧!

== 
try
     ShowModal;
  finally
    Free;   
那为什么这里还要Free?

procedure TFrm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  FrmMain.Show;
  self.Destroy;
end;
那就是说是不是不用 在Close时加这句 self.Destroy; ??

越来越不明白了。。

是不是动态创建以后,就不用管它了,不用去Destroy,也不用去Free??
那下回再用到那个窗体是不是直接Show就好了? 它还在吗?



#8


FreeAndNil(MyForm);

#9


打开project-> options->forms看看你的form是在auto-create forms还是在available forms
如果在auto-create forms那么在project->viewsource看到  Application.CreateForm(TForm1, Form1);这是自动创建了;如果available forms那你需要动态创建
try
  fm1 := Tform1.Create(nil);
  showmodal;
finally
  FreeAndnil(fm1);
end;

#10


那如果不是 ShowModal的话

如果Frm1,frm2都要用到动态创建的Frm3

那比如在Frm1里先动态Create Frm3,再Frm3.show --先不在Frm1里释放

而然后Frm2要用到的话,直接就Frm3.show,用完后再FreeAndNil(frm3)

这样行吗?

#11


...
try
  Application.CreateForm(TFrmTemp,FrmTemp);
  FrmTemp.ShowModal;
finally
  FreeAndNil(FrmTemp);
end;

#12


一个动态创建的Frm在Close之后,下回再Show要不要再次Create动态创建?

像Close,Destroy有什么不一样? 我怎么感觉都一样

#13


1、下次要不要再次创建要看你这个窗体对象的生存周期,基本概念
2、Close是关闭窗体,就是不显示了(隐藏了),但是这个对象还在,下次你可以调用Show再显示(前提如1),Destroy是释放窗体对象,释放了就不能再Show了,Free功能与Destroy基本相同,但是它会先检测一下自己是不是空指针,不是才会调用Destroy;
3、一般情况下使用Free

#14


我做了个测试:
procedure TForm1.Button1Click(Sender: TObject);
begin
    if form2=nil then
    begin
      showMessage('frm2 is nil now');
      form2:=Tform2.Create(application);
      try
        form2.ShowModal;
        finally
        //freeandNil(form2);   // freeAndNil 以后才可以再按下Btn
       form2.Free;      // 若是Free则再次按Btn会出错。。
      end; //try
end; //proc

procedure TForm1.Button2Click(Sender: TObject);
begin
 if form2=nil then
        showMessage('frm2 is nil after free')
      else
        begin
         showMessage('frm2 is not nil after free');
        form2.ShowModal;
         end;

end;


1.按下Form1的Btn1,模态显示Form2
2.按Form2的Cancel按钮关闭
3.按下From1的Btn2
结果: 若Btn1Click的程序中用的是 Finally form2.Free;   则到第3步会出错,显示完“'frm2 is not nil after free'”后,就出错了

而若  若Btn1Click的程序中用的是 Finally FreeAndNil(form2),则第3步显示完 'frm2 is nil after free'后,还可以再显示Form2

我不明白了: 不是说Free就是把窗口释放了吗?为什么还不是为成Nil? 那FreeAndNil和Free又差在哪了?

Free功能与Destroy基本相同,但是它会先检测一下自己是不是空指针,不是才会调用Destroy;
==Free不能把窗口变成Nil啊?

#15


还有个非模态框怎么释放自己?

就是在Frm1中Create了Frm2,再Frm2.show

现在要Frm2关闭的时候自己释放自己
我这样写:
procedure TFrm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
//  freeAndNil(self);
self.destroy;
end;

两个都不行,Free应该也不行

那要怎么自己将自己Nil掉?

#16


self.release;

#17


Free就是单纯释放,并没有将其置成空(nil);FreeAndNil是释放并置为空

#18


mark

#19


引用别处“实例就是类在内存里面的对象,占用两个部分的内存空间:一个是栈里面的对象指针空间,另外一个就是堆里面的对象实例空间,
两个部分应该是对应的,所以释放的时候要主要不要只释放了堆里面的对象实例空间而不释放栈中的指针空间....  
 
例如在将一个窗体释放的时候,不应该只将对象释放,如Self.Free  
 
而同时应该将指针进行释放,所以需要使用FreeAndNil(Self)这个句子”

#20


谢谢上面所有回的


procedure ShowForm(FormClass: TFormClass):integer;
begin
  With FormClass.Create(Application) do
 try
     ShowModal;
  finally
    Free;         // 这个不明白,finally后面跟的是不是不管Try部分
  end;
result:=**
end;

那怎么上面这段程序这么流行, 我看书里都这样
都没再Nil的,真奇怪。。


#21


mark

#22


destroy的方法就是判断是否为nil 不是就free

#23


self.destroy

#24


action:=caFree