为什么在访问对象之前我不应该使用“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条经验 获得超4个赞
Free
有一些特殊的逻辑:它检查是否Self
是nil
,如果是这样,它返回而不做任何事情-这样你就可以安全地调用X.Free
,即使X
是nil
。当你编写析构函数时,这很重要 - 大卫在他的答案中有更多的细节。
您可以查看源代码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
,只要它们是静态(即,不是virtual
或dynamic
)实例方法(感谢David Heffernan的文档链接)。但是在Delphi库中,Free
我所知道的唯一方法是使用这个技巧。
因此,Assigned
在调用之前,您无需检查变量是否存在Free
; 它已经为你做到了。这就是为什么建议是调用Free
而不是Destroy
直接调用的原因:如果你在nil
引用上调用了Destroy ,你就会遇到访问冲突。
添加回答
举报
0/150
提交
取消