我正在使用此代码检查是否创建了TStringList
:
procedure TForm1.Button1Click(Sender: TObject);
var
sVariable : TStringList;
begin
if not Assigned(sVariable) then
sVariable:= TStringList.Create;
end;
但条件总是False
,为什么会这样?如何检查是否创建了TStringList
对象?
P.S。我知道有一个类似的问题问题,我尝试了在那个问题上发布的解决方案,但它对我不起作用。
答案 0 :(得分: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;
请注意,在上面的代码中,我已经包含一个(强制IMHO)try...finally
块来释放内存。如果未分配sVariable
,则它仍为nil
,在这种情况下,sVariable.Free
将不执行任何操作。这是Delphi中常见的最佳实践模式。
答案 1 :(得分:8)
您可以假设未创建对象和变量initialized with garbage(因为它是局部变量)。只需创建你的StringList,一切都很好。
答案 2 :(得分:7)
首先:你发布的代码毫无意义。因为sVariable是局部变量,所以它总是未初始化的。 但与对象范围中的变量不同,未初始化并不意味着它是零。 Delphi不会将局部变量设置为nil。所以sVariable包含一个完全随机的值。 Assigned()仅检查值是否为nil - 而不是它是否指向对象的有效实例。
答案 3 :(得分:3)
你可以直接这样做,因为它是一个局部变量
procedure TForm1.Button1Click(Sender: TObject);
var
sVariable : TStringList;
begin
sVariable:= TStringList.Create;
end;
答案 4 :(得分: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;