TStringList局部变量未初始化为nil - 为什么?

Cyp*_*rUS 2 delphi tstringlist delphi-7

我正在使用此代码来检查是否TStringList创建:

procedure TForm1.Button1Click(Sender: TObject);
var

  sVariable : TStringList;
begin
   if not Assigned(sVariable) then
   sVariable:= TStringList.Create;
end; 
Run Code Online (Sandbox Code Playgroud)

但条件False总是如此,为什么会发生这种情况?如何检查TStringList对象是否已创建?

Ps我知道有一个类似的问题问题,我试过在那个问题上发布的解决方案,但它对我不起作用.

Arn*_*hez 15

当您在堆栈上分配对象引用时,它会填充随机值(即堆栈上的先前值 - 在某些边界情况下可能为零).这是设计的.

为了检查变量是否已初始化,您将首先手动将其设置为nil.这是一个非常快速的任务.

典型的代码模式可能是:

procedure TForm1.Button1Click(Sender: TObject);
var
  sVariable : TStringList;
begin
  sVariable := nil; // initialize explicitely
  try
    (...) // in this hidden part sVariable may be instantiated
    if not Assigned(sVariable) then // instantiate if not already done
      sVariable:= TStringList.Create; 
    (...)
  finally
    sVariable.Free; // will do nothing if sVariable=nil
  end;
end; 
Run Code Online (Sandbox Code Playgroud)

请注意,在上面的代码中,我已经包含一个(强制恕我直言)try...finally块来释放内存.如果sVariable没有分配,它仍然是nil,并且在这种情况下sVariable.Free将什么都不做.这是Delphi中通常的最佳实践模式.


Hei*_*cht 8

您可以假设没有创建对象,并且使用garbage初始化变量(因为它是局部变量).只需创建你的StringList,一切都很好.

  • `if Assigned(sVariable)`通常是正确的方法.但在你的情况下,检查是无关紧要的.您_know_表示尚未创建列表.你的局部变量最初包含垃圾,这意味着变量指向一些实际上不包含TStringList的内存位置.关键是:变量不是nil,但也不包含有效的TStringList.你不能检查这个.你知道这个 ;) (8认同)

Mic*_*ael 7

首先:你发布的代码毫无意义.因为sVariable是局部变量,所以它总是未初始化的.但与对象范围中的变量不同,未初始化并不意味着它是零.Delphi不会将局部变量设置为nil.所以sVariable包含一个完全随机的值.Assigned()仅检查值是否为nil - 而不是它是否指向对象的有效实例.

  • *Delphi不会将局部变量设置为nil*不是100%为真:它会初始化所有引用计数值,即`字符串,变量,数组,接口`类型的局部变量,它们是无效的.它不会像在OP代码中那样设置对类的本地引用. (2认同)