为什么Delphi对象分配甚至在调用.Free? [英] Why are Delphi objects assigned even after calling .Free?

查看:119
本文介绍了为什么Delphi对象分配甚至在调用.Free?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Delphi中,为什么在调用析构函数后,Assigned()函数仍然返回True?



下面的示例代码将会将sl仍然分配控制台。



但是,我可以调用FreeAndNil(sl);它不会被分配。



我已经在Delphi中编程了一段时间,但这对我来说是没有意义的。



有人可以解释吗?

 程序Project1; 
{$ APPTYPE CONSOLE}
使用SysUtils,Classes;

$ var
sl:TStringList;

begin
sl:= TStringList.Create;
sl.Free;
如果分配(sl)然后
WriteLn('sl仍然分配')
else
WriteLn('sl未分配');
结束。

我尝试比较VCL操作... FreeAndNil是简短而甜美,有意义:

 程序FreeAndNil(var Obj); 
var
P:TObject;
begin
P:= TObject(Obj);
TObject(Obj):= nil; //清除引用之前销毁对象
P.Free;
结束

但是TObject.Free是神秘的汇编器,我不明白:

  procedure TObject.Free; 
asm
TEST EAX,EAX
JE @@ exit
MOV ECX,[EAX]
MOV DL,1
CALL dword ptr [ECX]。 vmtDestroy
@@ exit:
end;


解决方案

如果你使用sl.Free,对象被释放但是变量sl仍然指向现在无效的内存。



使用FreeAndNil(sl)来释放对象并清除指针。



顺便说一句,如果你这样做:

  var 
sl1,sl2:TStringList;
begin
sl1:= TStringList.Create;
sl2:= sl1;
FreeAndNil(sl1);
// sl2仍然被分配,必须单独清除(不用FreeAndNil,因为它指向已经释放的对象。)
end;




程序TObject.Free;
asm
TEST EAX,EAX
JE @@ exit //如果指针为零,则跳转到退出。
MOV ECX,[EAX]
MOV DL,1
CALL dword ptr [ECX] .vmtDestroy //调用清理代码(和析构函数)。
@@ exit:
end;


In Delphi, why does the Assigned() function still return True after I call the destructor?

The below example code will write "sl is still assigned" to the console.

However, I can call FreeAndNil(sl); and it won't be assigned.

I've been programming in Delphi for a while, but this never made sense to me.

Can someone explain?

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.

I tried comparing the VCL operations... FreeAndNil is short and sweet and makes sense:

procedure FreeAndNil(var Obj);
var
  P: TObject;
begin
  P := TObject(Obj);
  TObject(Obj) := nil;  // clear the reference before destroying the object
  P.Free;
end;

But TObject.Free is in mysterious assembler, which I don't understand:

procedure TObject.Free;
asm
        TEST    EAX,EAX
        JE      @@exit
        MOV     ECX,[EAX]
        MOV     DL,1
        CALL    dword ptr [ECX].vmtDestroy
@@exit:
end;

解决方案

If you use sl.Free, the object is freed but the variable sl still points to the now invalid memory.

Use FreeAndNil(sl) to both free the object and clear the pointer.

By the way, if you do:

var
  sl1, sl2: TStringList;
begin
  sl1 := TStringList.Create;
  sl2 := sl1;
  FreeAndNil(sl1);
  // sl2 is still assigned and must be cleared separately (not with FreeAndNil because it points to the already freed object.)
end;




procedure TObject.Free;
asm
    TEST    EAX,EAX
    JE      @@exit              // Jump to exit if pointer is nil.
    MOV     ECX,[EAX]           
    MOV     DL,1
    CALL    dword ptr [ECX].vmtDestroy  // Call cleanup code (and destructor).
@@exit:
end;

这篇关于为什么Delphi对象分配甚至在调用.Free?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆