它可能不相关,但我最近重新安装了Delphi XE2。
我有一个变量path
(TPath类型,一个TMS Gogole映射的东西,虽然我怀疑这很重要)。
我在调试器中暂停并评估path
,其评估为Nil
。
如果我跑,我会得到一个例外,Read of address 0
,我怀疑是因为这个。
当我然后评估Assigned(path)
path = Nil
它True
时ShowMessage
(当我停在var
行时执行相同的结果)
有人可以向我解释一下吗?
清洁&重建没有任何改变。可能最好删除&重新安装Delphi?
(向@mbratch道歉,我使用path
进行演示,真实姓名是This was retested here with:
}
[更新]由TMS提供并为他们工作的完整代码示例(在不同的领域,这也是我在这里问的原因)。
uses
uwebgmapspolylines;
procedure TForm1.FormCreate(Sender: TObject);
var
p: TPath;
begin
p := TPath.Create;
if Assigned(p) then
ShowMessage('creation OK');
end;
and this proves the correct creation of TPath returns a valid instance.
if Assigned(p) then
当我停在p
并评估Nil
时,我得到Assigned(p)
,但当我评估True
时,我得到p <> Nil
。
当我将光标悬停在IDE中的变量声明上时,显示该类型是在UWebGMapsPolyLines中声明的
[更新]两票结束?真的吗?我想那些人认为这不可能 - 而且它就是!!!
奇怪的是@j尝试了它并获得了p = Nil
。但是,我在第二台PC上尝试了它,并且仍然使用由TMS提供的此处发布的代码获得if System.Assigned(p)
。
我承认这看起来很奇怪,但我可以在2台电脑上重现它。 P是Nil,但它是Assigned()。
我没有Assigend()的代码进入。此外,我稍微将代码更改为显式{{1}},但仍然得到相同的结果。有什么建议吗?
答案 0 :(得分:2)
我使用了你的代码(使用Delphi XE2),发现了这个:
您是否对FOwner = nil
p = nil
感到困惑? TPath
继承自TPersistent
,因此您可以将其传递给所有者(尽管这样做是可选的)。例如,您可以这样做:
p := TPath.Create(self);
修改强>
试试这个:
var p:TPath
begin
*1 if assigned(p) then ShowMessage('foo');
p:=nil;
if assigned(p) then ShowMessage('bar');
p:=TPath.Create;
if assigned (p) then ShowMessage('ok');
end;
将断点放在*1
上 - 您应该在监视器或局部变量窗口中看到:
p *Inaccessible Value*
非引用计数引用类型的局部变量未初始化为零/零 - 它们包含分配给它们的空间中发生的任何随机数据。 '无法访问的值'意味着无论随机数据是什么,它都不会指向程序内存空间中的可读内存地址。
步入下一行 - &gt; 'foo' - &gt; if assigned(p)...
你看到的消息......为什么?! Assigned
只检查nil
- 因为局部变量未初始化,Assigned返回true(它不知道你给它一个未初始化的局部变量 - 它只知道你给它的东西不是{{ 1}})。这也是为什么释放未初始化的局部变量是个坏主意。
步入下一行 - &gt; p:= nil - &gt; nil
当您跳过p:= nil时,您会看到无法访问的值更改为:
if assigned(p)...
你不会看到消息'bar'(记住,分配(p)只检查 p nil
)。请注意nil
在手表中是赤裸裸的 - 没有括号!一直到最后,您会在手表创建后再次看到nil
的值更改:
p
就像Sertac在评论中解释的那样,当一个对象被创建时,watch / locals窗口会在括号中显示它们的成员内容。以上显示 p (nil)
不是p
(没有括号),它不是未初始化的(即:不可访问的值),并且它还包含一个成员字段(展开显示为nil
),该字段已初始化为nil且尚未赋值。
简短的教训是FOwner
仅对字段或全局变量非常有用,而对非引用计数的局部变量非常有用 - 前者在创建对象时初始化为Assigned
,后者不是(当你输入方法时)。