这个问题是stackoverflow上人们特别评论的延续,我现在已经看过几次不同的时间了.我和教我Delphi的开发人员一样,为了保证安全,if assigned()在释放对象之前,以及在做其他各种事情之前总是先做检查.但是,我现在被告知我不应该添加此支票.我想知道如果我这样做,应用程序编译/运行的方式是否存在任何差异,或者它是否会对结果产生影响...
if assigned(SomeObject) then SomeObject.Free;
Run Code Online (Sandbox Code Playgroud)
假设我有一个表单,我在表单创建时在后台创建一个位图对象,并在完成后释放它.现在我想我的问题是,当我试图访问可能在某些时候可能已经免费的对象时,我已经习惯了对我的很多代码进行检查.即使没有必要,我也一直在使用它.我喜欢彻底......
unit Unit1;
interface
uses
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 …Run Code Online (Sandbox Code Playgroud) 在Delphi中,为什么在调用析构函数后Assigned()函数仍然返回True?
下面的示例代码将向控制台写入"sl仍然已分配".
但是,我可以打电话给FreeAndNil(sl); 它不会被分配.
我已经在Delphi中编程了一段时间,但这对我来说没有意义.
谁能解释一下?
program Project1;
{$APPTYPE CONSOLE}
uses SysUtils, Classes;
var
sl : TStringList;
begin
sl := TStringList.Create;
sl.Free;
if Assigned(sl) then
WriteLn('sl is still assigned')
else
WriteLn('sl is not assigned');
end.
Run Code Online (Sandbox Code Playgroud)
我尝试比较VCL操作... FreeAndNil简短而且很有意义:
procedure FreeAndNil(var Obj);
var
P: TObject;
begin
P := TObject(Obj);
TObject(Obj) := nil; // clear the reference before destroying the object
P.Free;
end;
Run Code Online (Sandbox Code Playgroud)
但TObject.Free是神秘的汇编程序,我不明白:
procedure TObject.Free;
asm
TEST EAX,EAX
JE @@exit
MOV ECX,[EAX]
MOV DL,1
CALL dword ptr [ECX].vmtDestroy
@@exit:
end;
Run Code Online (Sandbox Code Playgroud) delphi ×2