为了账号安全,请及时绑定邮箱和手机立即绑定

为什么在访问对象之前我不应该使用“if Assigned()”?

为什么在访问对象之前我不应该使用“if Assigned()”?

为什么在访问对象之前我不应该使用“if Assigned()”?这个问题是stackoverflow上人们特别评论的延续,我现在已经看过几次不同的时间了。我和教我Delphi的开发人员一样,为了保证安全,if assigned()在释放对象之前,以及在做其他各种事情之前总是先做检查。但是,我现在被告知我不应该添加此支票。我想知道如果我这样做,应用程序编译/运行的方式是否存在任何差异,或者它是否会对结果产生影响...if assigned(SomeObject) then SomeObject.Free;假设我有一个表单,我在表单创建时在后台创建一个位图对象,并在完成表单时释放它。现在我想我的问题是,当我试图访问可能在某些时候可能已经免费的对象时,我已经习惯了对我的很多代码进行检查。即使没有必要,我也一直在使用它。我喜欢彻底......unit Unit1;interfaceuses   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,   Dialogs;type   TForm1 = class(TForm)     procedure FormCreate(Sender: TObject);     procedure FormDestroy(Sender: TObject);   private     FBitmap: TBitmap;   public    function LoadBitmap(const Filename: String): Bool;     property Bitmap: TBitmap read FBitmap;   end;var   Form1: TForm1;implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);begin   FBitmap:= TBitmap.Create;   LoadBitmap('C:\Some Sample Bitmap.bmp');end;procedure TForm1.FormDestroy(Sender: TObject);begin   if assigned(FBitmap) then begin //<-----     //Do some routine to close file     FBitmap.Free;   end;end;function TForm1.LoadBitmap(const Filename: String): Bool;var   EM: String;   function CheckFile: Bool;   begin     Result:= False;     //Check validity of file, return True if valid bitmap, etc.   end;begin   Result:= False;   EM:= '';   if assigned(FBitmap) then begin //<-----     if FileExists(Filename) then begin       if CheckFile then begin         try           FBitmap.LoadFromFile(Filename);         except现在让我们说我正在引入一个名为TMyList的新自定义列表对象TMyListItem。对于此列表中的每个项目,我当然必须创建/释放每个项目对象。创建项目有几种不同的方法,以及一些销毁项目的不同方法(添加/删除是最常见的)。我确信将这种保护放在这里是一种非常好的做法......在许多情况下,至少我希望在我尝试释放它之前仍然创建对象。但是你永远不知道未来在对象被释放之前会发生什么样的滑动。我总是使用这张支票,但现在我被告知我不应该这样,而且我仍然不明白为什么。
查看完整描述

3 回答

?
Helenr

TA贡献1780条经验 获得超3个赞

Free有一些特殊的逻辑:它检查是否Selfnil,如果是这样,它返回而不做任何事情-这样你就可以安全地调用X.Free,即使Xnil。当你编写析构函数时,这很重要 - 大卫在他的答案中有更多的细节。

您可以查看源代码Free以了解其工作原理。我没有方便的Delphi源代码,但它是这样的:

procedure TObject.Free;begin
  if Self <> nil then
    Destroy;end;

或者,如果您愿意,可以将其视为等效代码,使用Assigned

procedure TObject.Free;begin
  if Assigned(Self) then
    Destroy;end;

您可以编写自己的方法来检查if Self <> nil,只要它们是静态(即,不是virtualdynamic)实例方法(感谢David Heffernan的文档链接)。但是在Delphi库中,Free我所知道的唯一方法是使用这个技巧。

因此,Assigned在调用之前,您无需检查变量是否存在Free; 它已经为你做到了。这就是为什么建议是调用Free而不是Destroy直接调用的原因:如果你在nil引用上调用了Destroy ,你就会遇到访问冲突。


查看完整回答
反对 回复 2019-08-17
  • 3 回答
  • 0 关注
  • 625 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信