-1

它可能不相关,但我最近重新安装了 Delphi XE2。

我有一个变量path(TPath 类型,一个 TMS Gogole 映射的东西,虽然我怀疑这很重要)。

我在调试器中停止并评估path,其评估为Nil

如果我运行,我会得到一个异常,Read of address 0我怀疑是因为这个。

Assigned(path)然后,当我同时评估path = Nil它演变为时True(当我在线停止时,结果相同ShowMessage- 执行))。

有人可以向我解释吗?

清理和重建没有任何改变。删除并重新安装Delphi会更好吗?

(向@mbratch致歉,我用var的是demo,本名是actully path


[更新] TMS 提供并为他们工作的完整代码示例(在不同的 tiem 区域,这也是我在这里问的原因)。

This was retested here with:

 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

当我将光标悬停在 IDE 中的变量声明上时,显示该类型是在 UWebGMapsPolyLines 中声明的


[进一步更新] 两票关闭?严重地?我猜来自那些认为这不可能的人 - 但它是!

奇怪的是,@j 尝试了它并得到了p <> Nil. 但是,我在第二台 PC 上进行了尝试,仍然可以p = Nil使用此处发布的代码,该代码由 TMS 提供。

我承认这看起来很奇怪,但我可以在 2 台电脑上重现它。P 是 Nil,但它是 Assigned()。

我没有 Assigend() 的代码可以进入。此外,我将代码稍微更改为显式if System.Assigned(p),但仍然得到相同的结果。有什么建议么?

分配,还是不分配?

4

1 回答 1

2

我完全使用了您的代码(使用 Delphi XE2)并发现了这个:

TPath 断点

TPath 手表

你可能会感到困惑FOwner = nilp = nilTPath继承自,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*

非引用计数引用类型的局部变量未初始化为零/零 - 它们包含碰巧在分配给它们的空间中的任何随机数据。 “不可访问的值”意味着无论随机数据是什么,它都不指向程序内存空间中的可读内存地址。

跳到下一行 --> 'foo' -->if assigned(p)...

您看到消息...为什么?! Assigned只检查nil- 因为局部变量没有初始化,所以 Assigned 返回 true (它不知道你给了它一个未初始化的局部变量 - 它只知道你给了它一些 not nil)。这也是为什么释放未初始化的局部变量是个坏主意的原因。

跳到下一行 --> p := nil -->if assigned(p)...

当您越过 p:=nil 时,您应该会看到Inaccessible Value更改为:

 p       nil

而且您不会看到消息“bar”(请记住,assign(p) 仅检查nil)。请注意,nil手表中是裸露的 - 没有括号!单步执行到最后,您p会在手表创建后再次看到它的值变化:

 p       (nil)     

就像 Sertac 在评论中解释的那样,创建对象后,监视/本地窗口会在括号中显示它们的成员内容。上面向我们展示了p不是nil没有括号),它不是未初始化的(即:not inaccessible value),并且它还包含一个成员字段(扩展显示它是FOwner),该字段已初始化为 nil 并且尚未分配价值。

简短的教训是,Assigned它只对字段或全局变量真正有用,而不是对非引用计数的局部变量有用——前者在nil创建对象时被初始化,后者不是(当你输入方法时)。

于 2013-06-10T14:18:52.347 回答