动态创建form常碰到一个问题就是必须在创建之前判断form是否已经存在,通常第一次创建的时候form肯定为nil,但是当使用完毕之后如果form.free后,form肯定不是nil,必须在form关闭之后在他的主调用form中动态freeandnil(form),或者form.free;form.nil;才能变成nil
我想知道有没有办法当form.free之后,form指针并不是nil的时候来判断form是否已经被free过了,是否能够正常创建一个新的对象。
这个问题困扰了很久了!

解决方案 »

  1.   

    用assigned()函数来判断一个对象变量是否为空.
    if not assigned(form) then
      form := tform.create(application);
    form.show;
      

  2.   

    if assigned(Form1) then freeandnil(Form1);
    Application.createform(TForm1,Form1);
    Form1.showmodal;
      

  3.   

    不过释放的时候不能用。FREE的方法,你需要用FREENADNIL函数来处理一个创建的OBJECT;
      

  4.   

    我就是想判断一个对象是否被free,不知道assigned是否能够判断这种情况呢?
    一个系统不是每个人都是用freeandnil,或者不是每一个form释放都能成为nil,所以必须判断这种情况
      

  5.   

    assigned只是判断窗体是否已经被创建了
      

  6.   

    个人感觉楼上各位的方法根本没有针对楼主的问题啊!当申明一个Form1的时候,只是在栈上创建一个四个字节的内存空间。直到调用构造器的时候才真正跑到堆上分配对象实际内存空间,也只有到了这个时候,前面分配的四个字节的对象指针的内容才有意义!当我们释放了Form1的时候,如果不释放栈上的对象指针,就会形成一个野指针,如果对野指针进行操作,马上就会出现一个AV访问错误....楼主的意思,我想就是在不释放对象指针的情况下去判断当前对象指针指向的对象是否还存在!个人认为没有任何现成的方法可以进行这种判断!如果使用Release、Free或Action:=caFree等方法将窗体释放掉后,此时窗体指针内容并不改变,这个时候用Assigned来判断虽然也可以判断窗体对象指针有意义,但实际窗体是根本不存在的!
      

  7.   

    FrameSniper兄,我想知道的就是这个,难道没有任何办法可以判断一个指针的地址是否真的有效吗?经常碰到这个问题,通常都要很严格的控制一个指针free后必须nil,或者读取指针的某一个属性来判断有效性,感觉这个办法很笨,感觉肯定有一些好的办法,等到这个问题解决了在接贴吧!
      

  8.   

    呵呵,幸好俺把这个文章连接放到Favorites里面了,地址如下:http://www.csdn.net/Develop/read_article.asp?id=9508不过你看后会感觉那根本不叫什么方法,至少不是你所希望的正规方法,通过调用一个成员方法来判断是否有异常被触发,呵呵,我不认为这是个好方法,而且感觉也没有方法,所以给你下了个结论没有合理的好方法!不过这个文章前面的一句话我到是认为很对----“其实这本不应该成为一个问题。因为对于程序设计者来说,他应该能够控制自己的程序不去访问一个无效的指针,因为所有的对象实例的创建和销毁都在他控制之下。”,不过,可能你在具体开发时有你自己的需求另外,你可以模仿FreeAndNil过程,在析构器里面对对象指针设置一个值,其实就是模拟FreeAndNil方法!
      

  9.   

    关注....
    难道free之后没有将此对象真正释放吗?
    可我操作Form时基本上都是动态创建的,而且都是CreateForm以后再free这个Form的,好象没出什么问题啊.
      

  10.   

    Free和Release一样都只是释放堆上的对象实体空间,栈上那个原本有意义的指针并没有释放!他们是同一个对象的两个组成部分,只释放一个而不释放另外一个不能叫彻底释放你不出问题是因为你没有调用野指针....
      

  11.   

    我也有个问题,为什么我把动态创建成的关闭键设成Form.Free的时候有时候能free成功,有时候失败呢?还有个问题,本来我在MainForm出现之前要动态创建一个form1,那个form1我用Form1.Showmodal显示在MainForm之前(但是为了调试程序的方便,我把Form1.Showmodal语句给屏蔽了),在这里我在MainForm中另外动态创建一个Form2的时候,并且执行Form2.Showmodal,用完之后,我把Form2关闭之后,为什么进不了MainForm了呢???
      

  12.   

    if Not Assigned(form1) then
       Form1:=TForm1.create(application)
    else
      Form1.show;
    在formclose事件中
     form1:=Nil;
     Action:=caFree;
      

  13.   

    我也有个问题,为什么我把动态创建成的Form的关闭键设成Form.Free的时候有时候能free成功,有时候失败呢?还有个问题,本来我在MainForm出现之前要动态创建一个form1,那个form1我用Form1.Showmodal显示在MainForm之前(但是为了调试程序的方便,我把Form1.Showmodal语句给屏蔽了),在这里我在MainForm中另外动态创建一个Form2的时候,并且执行Form2.Showmodal,用完之后,我把Form2关闭之后,为什么进不了MainForm了呢???
      

  14.   

    menliwxj(有缘)说的方法可以,
    haipin(似水柔情) 的方法也行;条条大路通罗马!
      

  15.   

    To SwordMan119我也有个问题,为什么我把动态创建成的Form的关闭键设成Form.Free的时候有时候能free成功,有时候失败呢?还有个问题,本来我在MainForm出现之前要动态创建一个form1,那个form1我用Form1.Showmodal显示在MainForm之前(但是为了调试程序的方便,我把Form1.Showmodal语句给屏蔽了),在这里我在MainForm中另外动态创建一个Form2的时候,并且执行Form2.Showmodal,用完之后,我把Form2关闭之后,为什么进不了MainForm了呢???-------------------------------------------------------------------怎么可能,在动态创建的Form的OnClose里面释放窗体可以使用三种方法:
    1. FreeAndNil(Self);
    2. Action:=caFree;
       Form1:=Nil;  //这里不能使用Self:=Nil;因为此时Self不等于Form1
    3. Self.Free或者Self.Release;
       Form1:=Nil;  //同上后面那个问题,最好给个代码来判断!
      

  16.   

    第二个问题简单的描述一下如下:
    在MainForm中:
    procedure TMainForm.FormActivate(Sender: TObject);
    var Enter: TEnter;             ←TEnter是一个form类
    begin
      Enter := TEnter.Create(Self);
      //Enter.ShowModal;           ←为了调试程序方便,我把这句先屏蔽
    end;procedure TMainForm.N5Click(Sender: TObject);
    var Information1: TInformation1;    //TInformation1也是一个form类
    begin
      Information1 := TInformation1.Create(Self);
      Information1.ShowModal;
    end;
    在Information1中如果我把他的关闭键写成free,就出现第二个问题了,不知道到什么回事。
    procedure TInformation1.CloseClick(Sender: TObject);
    begin
      Information1.Free;
    end;
      

  17.   

    如果你在工程文件中用Application.CreateForm来创建窗体,第1个Form将被作为程序的主窗体.如果该窗体关闭了,程序也将退出.
    swordman119(★人无名剑也无名★) :
    你的关闭窗体的方法不正确.你的
    procedure TInformation1.CloseClick(Sender: TObject);
    begin
      Information1.Free;---改为Close;
    end;
      

  18.   

    如果不是MDI窗体,只是用show方法显示窗体,你应该在Form的OnClose事件里将Form对象名赋值为nil,当然如果你用的是局部变量,则不需如此做了.
      

  19.   

    请见我以前的帖子http://expert.csdn.net/Expert/topic/1903/1903152.xml?temp=.2238733
      

  20.   

    用调用对象的方法,产生异常来判断,我觉得不好,
    还是在Screen.Forms中查找比较好,虽然慢一点,但调用次数不多,无伤大雅!
      

  21.   

    To  menliwxj(有缘) 
    用Close我知道的,但是为什么用了free之后就出现这问题了呢?
    有一点我不是很明白,show方法和showmodal方法有什么区别呢?
      

  22.   

    我曾经把一个动态创建的窗体free掉之后,用语句
    if not Assigned(ChildForm) then
      begin
        ChildForm := TChildForm.Create(self);
        ChildForm.ShowModal;
      end;
    调用,发现没成功啊。不知道free到底是怎么回事。
      

  23.   

    if Not Assigned(form) then
       Form1:=TForm1.create(application)
    else
      form.show;这样就可以了
      

  24.   

    VisualLion(狮子) 的帖子已经说明了一切
      

  25.   

    我写上面那个语句的意思是free之后好象没完全free啊。
      

  26.   

    procedure TForm1.Button1Click(Sender: TObject);
    begin
     try
      if not Assigned(form2) then
         form2:=TForm2.create(Application);
       Form2.ShowModal;
      finally
       form2.free;
       form2:=nil;
      end;
    end;