以我的理解能力,FreeAndNil其实就两句话
procedure FreeAndNil(var Obj:TObject);
begin
  Obj.Free;
  Obj:=Nil;
end;
但是我看了VCL的源码,发现完全不是这样的,代码如下
procedure FreeAndNil(var Obj);
var
  Temp: TObject;
begin
  Temp := TObject(Obj);
  Pointer(Obj) := nil;
  Temp.Free;
end;
为什么要使用一个中间变量呢?为什么要先nil再Free呢?类型转换是必须的吗?为什么参数不直接声明为TObject类型呢?

解决方案 »

  1.   

    易用啊
    调用的时候就不用freeandnil(Tobject(var))了
      

  2.   

    程序设计有一个原则就是无论发生任何异常或错误都不影响其下的代码状态.
    Borland这样写我个人认为是Pointer(Obj):=nil;//绝对不会出现错误或抛出异常但Temp.free可能会.所以如果先free再nil那么就要进行异常处理,这样这简单的小function是没必要也不够清晰.
      

  3.   

    不会的啊,TObject类声明为参数类型,可以传递任何类型进去,无需强制类型转换。
    Rain的解释还不太懂,先nil再free就不异常了?该异常的你调用Temp.free还是异常的啊
      

  4.   

    这个很好理解: 在Obj.Free; Obj:=nil;中,如果Obj.Free出现错误,例如Obj本身是非法对象,那么抛出异常后,Obj:=nil将不会执行,过程目的Obj为nil没达到;而后面的就不同,无论Obj是否非法,都会被设置为nil,即使Temp.Free抛出异常。所以,该函数的目的达到了,即Obj为nil。
    至于,参数类型为什么不直接写为TObject,可能是考虑对象有时赋给其它类型的指针甚至一个整数类型
      

  5.   

    按楼上的解释,函数应该叫 NilAndFree 才对呀,呵呵。正真原因我也不太明白,是不是与接口引用计数什么的有关呢...
      

  6.   

    按楼上的解释,函数应该叫   NilAndFree   才对呀,呵呵。 
    =============================================================================================
    为什么要将简单问题项复杂呢?and本就是并列关系,FreeAndNil和NilAndFree有区别吗?如果Obj是合法对象,固然是FreeAndNil;而当Obj为非法对象时,Free已没有意义,直接置为Nil,FreeAndNil的双重目不也同样达到了吗!所以,我认为Delphi的源码就是考虑这一点才这么写的,这很好理解,和“接口引用计数什么的”应该毫无关系。当然,你认为我解释不对,要往复杂处想,我也无话可说,毕竟不伤谁的皮肉!哈哈!!!
      

  7.   

    同意2楼和5楼
    free出错的机会比置空要大,
    因此先置空,再Free,如果不用临时变量的话
    置空以后,就没法Free了至于用无类型参数而不用TObject,
    应该考虑的是即使传入其它类型比如指针、数值时,
    至少保证能置为nil