delphi – 为什么某些属性超出了监视列表的范围,而其他属性则没
首先,对于冗长的代码示例感到抱歉,但我认为需要说明我的问题.
作为调试帮助,我经常在我的对象上引入一个“DebugString”方法,它返回一个简洁的对象摘要.但有时我的对象太复杂而无法在单个字符串中进行最佳表示,因此我使用字符串列表.现在,我想使用Delphi中出色的调试可视化器来监视我的对象.我这样做的方法是引入一个带有getter的属性来重建stringlist. 这种方法有效,但对于我追踪的每一行,属性都超出了范围,因此我必须再次单击观察窗口中的放大镜才能看到该值.为什么是这样? 要重现,请创建一个新的控制台应用程序: program Project1; {$APPTYPE CONSOLE} uses SysUtils,Classes; type TMyClass = class private FInternalData : array[0..4] of integer; FDebugStringList : TStringList; procedure RebuildDebugStringlist; function GetDebugStringList: TStringList; function GetDebugString : string; public constructor Create; destructor Destroy; override; procedure Scramble; property DebugStringList : TStringList read GetDebugStringList; property DebugString : string read GetDebugString; end; constructor TMyClass.Create; begin FDebugStringList := TStringList.Create; end; destructor TMyClass.Destroy; begin FDebugStringList.Free; inherited; end; function TMyClass.GetDebugString: string; var I : integer; begin Result := 'Object state: '; for I := 0 to 3 do Result := Result + inttostr(FInternalData[I])+' '; end; function TMyClass.GetDebugStringList: TStringList; begin RebuildDebugStringlist; Result := FDebugStringlist; end; procedure TMyClass.RebuildDebugStringlist; var I : integer; begin FDebugStringList.Clear; FDebugStringList.Add('Object state:'); for I := 0 to 4 do FDebugStringList.Add(inttostr(FInternalData[I])); end; procedure TMyClass.Scramble; var I : integer; begin for I := 0 to 4 do FInternalData[I] := Random(100); end; var vMyObj : TMyClass; begin vMyObj := TMyClass.Create; try vMyObj.Scramble; vMyObj.Scramble; vMyObj.Scramble; finally vMyObj.Free; end; readln; end. >为“vMyObj.DebugStringList”和“vMyObj.DebugString”添加监视 为什么可视化器会说手表超出范围?我怎样才能解决这个问题? PS:我知道我可以编写调试可视化工具,但我在一些自动测试中使用“DebugString”和“DebugStringList”,我真的很想以这种简单的方式使用它们. 更新:我使用Delphi XE 更新2: 解决方法
它超出了范围,因为这正是Scramble执行时发生的情况.该错误可能是因为可视化器在返回范围时不会刷新.还没有看过TStrings可视化工具,但是解决方法是使用无类型指针变量到FDebugStringList并将该TStringList的类型转换为该derefenced指针.
var vMyObj : TMyClass; vSL: Pointer; {$OPTIMIZATION OFF} begin vMyObj := TMyClass.Create; try vSL := @(vMyObj.FDebugStringList); 和手表: TStringList(vSL^) 当您现在打破第二次争夺时,打开vSL的可视化工具,您将看到FDebugStringList的内容.当您跨过第二次争夺时,您可以看到可视化工具“在争夺执行时思考,然后在您返回主级别时自我刷新”. 陷阱:您确实需要确保无法优化无类型指针变量.因此要么对它进行一些非平凡的使用,要确保在调试时关闭优化. 编辑:不幸的是,似乎工作周围显示过时的价值观.见Svein的评论. 更新 免责声明:我不是ToolsAPI专家.对StringListVisualizer和ToolsAPI单元的粗略检查表明,RefreshVisualizer是“{当可视化器的数据需要刷新时调用}”.此外,字符串“RefreshVisualizer”仅在ToolsAPI单元的接口声明中找到,并在StringListVisualizer单元中声明和实现.所以我现在的猜测是调试器在第三次Scramble调用时返回停止时应该调用RefreshVisualizer,但是没有.在我看来值得一个质量控制报告.至少它是“用户体验的缺点”. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |