代码之家  ›  专栏  ›  技术社区  ›  Bharat

哪个更好:免费还是免费?

  •  44
  • Bharat  · 技术社区  · 14 年前

    自由和无的基本区别是什么?

    是FreeAndNil=自由+零?

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

    5 回复  |  直到 4 年前
        1
  •  47
  •   PresleyDias    12 年前

    看到了吗

    并看看实施情况:

    procedure FreeAndNil(var Obj);
    var
      Temp: TObject;
    begin
      Temp := TObject(Obj);
      Pointer(Obj) := nil;
      Temp.Free;
    end;
    

    示例

    考虑以下代码:

    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;
    

    这将在我的桌面上创建错误或无效(空)位图,因为我尝试使用已释放的对象。是的,尽管如此 bm 已经释放,它仍然是“分配的”,即。 bm公司 仍然指向内存地址,即使那里没有(可用的)东西。为了克服这一点,我们可以 bm := nil ,作为一种保护 assigned(bm) 将返回false,正如您所希望的那样。或多或少, FreeAndNil(bm) bm.Free; bm := nil . 第一条语句释放所有内存(以及对象使用的操作系统资源、CPU时间等),并且 bm:=无 设置“指针” bm公司 nil ,所以 不再指向对象以前所在的位置,但不再是。这样你(和你喜欢的人) assigned )不会上当相信还有位图对象。

    讨论

    FreeAndNil(foo) 而不是 foo.Free foo := nil 可能不会花费太多纳秒来执行 assigned(foo) = false foo 释放对象后,可以继续 foo.free . 实际上,有些人会认为在很多情况下(但不是所有情况下),试图使用一个释放对象的变量本身就是一个bug(当然,在有些情况下,你是故意这样做的——你有一个对象 有时分配,有时不分配。)

        2
  •  20
  •   Kromster Satyajit    10 年前

    基本上,FreeAndNil将引用设置为 然后释放对象。这会将其标记为未分配。因此,您需要使用FreeAndNil的唯一原因是您的代码是否要重用引用。如果你在一个毁灭者或者 阻止,释放你永远不会再接触的物体,只要使用免费的。

    Delphi Memory Management Made Simple 例如,当我发现它有用的时候。Mghie在底部的评论也值得一读。

        3
  •  9
  •   Jeroen Wiert Pluimers    14 年前

    我会用另一种方式回答。

    也许,用 nil 释放你的物体后并不总是一个好主意。

    这样,您就不必区分从未使用过的引用(因此是 ),以及已使用但不应在将来使用的引用。

    所以,用一个神奇的数字来填充它(类似于 FastMM

    --杰罗恩

        4
  •  7
  •   RRUZ    14 年前

    Free FreeAndNil 将对象引用设置为nil。

    你可以查看这些关于使用免费或免费和无的讨论链接

        5
  •  3
  •   IceCold    3 年前

    即使看起来与Free没有太大区别,FreeAndNil也能帮助您在代码中查找bug。

    它如何拯救你的屁股(免费后进入)

    但这还不是全部。如果你运气不好,程序不会立即崩溃。或者它永远不会崩溃,相反,它会读取或写入随机的内存块。这才是真正的痛苦开始的地方!

    它会损害你的程序吗?
    正如其他人已经指出的,FreeAndNil本身并不坏。FreeAndNil函数不是坏的/过时的或类似的东西,它不会损坏您的代码。 它是一个合法的RTL函数,释放和对象,然后将其指针指向NIL。


    有些人会争辩说,依赖FreeAndNil可能会导致或表明设计缺陷,但他们无法以任何方式证明这一点。这只是他们个人的选择。另一方面,一个程序,随机和无缺陷地(他。。。我只是创造一个新词)因为你拒绝使用FreeAndNil是事实而不是意见。


    我甚至在局部变量上使用FreeAndNil。在局部变量上使用它似乎毫无意义,因为一旦退出过程,变量就会消失。
    你可以在以后的某个时候,在释放对象之后,在过程的末尾添加更多的代码;将(意外地)尝试访问已释放对象的代码。如果物体是零,宝贝,即时AV( example ).

    资源猪?
    一些超级保守的程序员可能会说这个简单的调用会浪费RAM和CPU资源。我也喜欢交付小型/快速/单片应用程序!
    但我不认为删除使用FreeAndNil会浪费超过几个字节的RAM和CPU周期。它不会对日常生活产生真正的影响。

    神与程序员

    赞成的意见
    梅森·惠勒(Mason Wheeler)已经指出了一篇文章,其中展示了使用FreeAndNil的“懒散创建”方法,我们有一天都使用了这个方法: http://tech.turbu-rpg.com/106/delphi-memory-management-made-simple


    没有确凿的证据。

    艾伦·鲍尔有一篇文章叫 A CASE when FreeAndNil is your enemy 暗示在非常特殊的情况下使用FreeAndNil(可视组件的析构函数)可能是不好的。这篇文章没有我们可以编译的代码,只有一些 自由零的场景 可以

    艾伦认为FreeAndNil应该被更好的方法所取代。例如使用FastMM。
    , this discussion 演示(使用可编译代码)FastMM失败,而FreeAndNil可以节省时间。



    在这一点上,我甚至希望有一小块具体的/可编译的代码来表明FreeAndNil可能会造成伤害。
    另一方面,我们有大量的例子(见链接)来说明FreeAndNil是如何拯救我们的。