哪个更好:免费或FreeAndNil?

Bha*_*rat 47 delphi

Free和FreeAndNil之间的基本区别是什么?

FreeAndNil = Free + Nil?

我什么时候应该使用Free,什么时候应该使用FreeAndNil?

当有人帮助我时,我没有得到这些.

提前致谢.

And*_*and 43

看到

并看看实现:

procedure FreeAndNil(var Obj);
var
  Temp: TObject;
begin
  Temp := TObject(Obj);
  Pointer(Obj) := nil;
  Temp.Free;
end;
Run Code Online (Sandbox Code Playgroud)

例子

请考虑以下代码:

procedure TForm1.FormCreate(Sender: TObject);
var
  bm: TBitmap;
begin
  bm := TBitmap.Create;
  bm.LoadFromFile('C:\Users\Andreas Rejbrand\Documents\RAD Studio\6.0\Demos\DelphiWin32\VCLWin32\Football\up.bmp');
  bm.Free;

  if Assigned(bm) then
    bm.SaveToFile('C:\Users\Andreas Rejbrand\Desktop\test.bmp')
  else
    ShowMessage('Cannot save! The bitmap does no longer exist!');
end;
Run Code Online (Sandbox Code Playgroud)

这将在我的桌面上创建错误或无效(空)位图,因为我尝试使用已释放的对象.是的,即使bm已被释放,它仍然被"分配",即bm仍然指向内存地址,即使那里没有任何东西(可用).为了克服这一点,人们可以设置bm := nil,作为保护,然后assigned(bm)将返回虚假,如人们想要的那样.或多或少,FreeAndNil(bm)是一种简写bm.Free; bm := nil.第一个语句释放所有内存(以及操作系统资源,对象使用的CPU时间等),并将bm := nil"指针"设置bmnil,以便bm不再指向对象所在的位置,但不再指向.通过这种方式,您(以及类似的例程assigned)不会因为相信仍然存在位图对象而被愚弄.

讨论

有人说你应该总是使用FreeAndNil(foo)而不是foo.Free.好吧,为什么不呢?附加指令foo := nil可能不会花费太多纳秒来执行,并且确实assigned(foo) = false是释放对象的非常好的属性.但话又说回来,如果你知道自己在做什么,并且知道foo在释放它之后再也不会再使用该物体,那么你可以坚持下去foo.free.实际上,有些人会争辩说,在许多情况下(但不是全部),尝试使用自由对象的变量本身就是一个错误.(当然,有些情况下你有意这样做 - 你有一个foo有时被分配的对象,有时却没有.)

  • 我甚至会说程序员应该通过使用foo来表达他的意图.当foo没有再次被引用时自由,FreeAndNil(foo)就是这样.当foo.Free会这样做时,不要使用FreeAndNil(foo),因为它向读者建议将foo_needs_设置为nil. (5认同)
  • "有些人会争辩说,在许多情况下(但不是全部),尝试使用已被释放的对象本身就是一个错误" - 这总是一个错误,而不是"有时".变量和对象是不同的野兽:变量有时可能被指定为"nil",但这不是一个零对象,只是一个未赋值的变量. (4认同)
  • +1 _但是,如果你知道你在做什么...... (4认同)

Mas*_*ler 18

基本上,FreeAndNil将引用设置为nil,然后释放对象.这标志着它是未分配的.因此,您需要使用FreeAndNil的唯一原因是您的代码将重用该引用.如果你在析构函数或最终块中,释放你永远不会再触摸的对象,只需使用Free.

有关我发现它有用的示例,请参阅Delphi Memory Management Made Simple.Mghie在底部的评论也值得一读.

  • 实际上,它将引用放在本地var中,nils引用,然后使用local var释放对象.FreeAndNil应该被命名为NilAndFree ...... :) (4认同)

Jer*_*ers 8

我会以不同的方式回答.

也许,nil在释放对象后填充对象引用并不总是一个好主意.

这样,您就没有区分从未使用过的引用(因此也是nil),以及已经使用过的引用,但不应该在将来使用.

因此,用一个幻数填充它(类似于FastMM内存管理器在释放这些块时可以对内存块的内容做的事情).

--jeroen


RRU*_*RUZ 6

@Bharat,和之间的区别在于Free,FreeAndNil除了对象使用的空闲内存外,还将FreeAndNil对象引用设置为nil.

您可以查看这些链接,了解有关使用Free或FreeAndNil的讨论