2

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

procedure TForm1.Button1Click(Sender: TObject);
var

  sVariable : TStringList;
begin
   if not Assigned(sVariable) then
   sVariable:= TStringList.Create;
end; 

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

Ps 我知道有人问过类似的问题,我尝试了该问题中发布的解决方案,但它对我不起作用。

4

5 回答 5

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; 

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

于 2011-11-04T10:53:45.300 回答
8

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

于 2011-11-04T10:35:20.790 回答
7

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

于 2011-11-04T10:48:04.723 回答
3

您可以直接执行此操作,因为它是局部变量

procedure TForm1.Button1Click(Sender: TObject);
var
  sVariable : TStringList;
begin
  sVariable:= TStringList.Create;
end;
于 2011-11-04T10:39:40.277 回答
3

在您更新问题后,我所看到的似乎很正常。

当您定义一个对象变量 (sVariable) 时,它不会被初始化,这与 Create 构造函数有关。在这种情况下,您甚至不必检查它是否存在。

procedure TForm1.Button1Click(Sender: TObject);
var
  sVariable : TStringList;
begin
   sVariable:= TStringList.Create;
   //Work with the stringlist e.g add items:
   sVariable.Add('Blah');
   //Make sure it finally gets freed 
   sVariable.Free;
end; 
于 2011-11-04T10:41:40.837 回答