(Delphi 6 with TChart,Win XP)
我试图从点系列中清除点数时出现了不稳定的行为,当然,这段代码曾经起作用。
基本上,我程序的这一部分会生成5个数据点并绘制它们。当我尝试使用OSC_Series.Clear清除它们时,我得到一个“List index out of bounds [0]”错误。
我检查确保我正在绘制的值没有什么奇怪的。一切都很好。然后我尝试了不同的东西来试图隔离并解决问题。
这是一些代码。
type
TksGraph_DataFrm = class(TForm)
.
.
.
private
OSC_Series: TPointSeries
public
end;
procedure TksGraph_DataFrm.cat7AnalysisInitialize(var P:TTest_Project);
begin
// Do a bunch of stuff.
// Set up the analysis data points series.
OSC_Series:=TPointSeries.Create(self);
AnalysisChart.AddSeries(OSC_Series);
with OSC_Series do
begin
Title:='';
HorizAxis:=aBothHorizAxis;
VertAxis:=aBothVertAxis;
SeriesColor:=clRed;
Pointer.Brush.Color:=clYellow;
Pointer.HorizSize:=4;
Pointer.VertSize:=4;
Pointer.Style:=psRectangle;
Pointer.Visible:=true;
LinePen.Color:=clBlack;
LinePen.Width:=1;
Linepen.Visible:=true;
ShowInLegend:=false;
XValues.Order:=LoNone;
end;
end;
procedure TksGraph_DataFrm.cat7AnalysisRefresh(var P:TTest_Project);
var X,Y:single;
begin
X:= some value
Y:= some value
// Plot the result.
OSC_Series.AddXY(X,Y);
showmessage(
'Count = '+inttostr(OSC_Series.Count)+#13+
'X = '+FloatToStr(X)+#13+
'Y = '+FloatToStr(Y)+#13+
'Plot-X = '+FloatToStr(OSC_Series.XValue[OSC_Series.Count-1])+#13+
'Plot-Y = '+FloatToStr(OSC_Series.YValue[OSC_Series.Count-1]));
end;
这是我用来重置系列的例程。我包含的代码有效且无效。
procedure TksGraph_DataFrm.cat7AnalysisClear(var P:TTest_Project);
var i:integer;
begin
// This should work, but it gives me the list out of bounds error
// unless the count is 0.
OSC_Series.Clear;
// This does not work, for obvious reasons. I get a "list out of
// bounds [3] for this one.
for i:=0 to OSC_Series.Count - 1 do OSC_Series.Delete[0];
// It seems this should work, but again I get the out of bounds [0]
// error.
repeat
OSC_Series.Delete(0);
until OSC_Series.Count = 0;
// This works. Don't ask me why.
showmessage('A - '+inttostr(OSC_Series.Count));
OSC_Series.Clear;
showmessage('B - '+inttostr(OSC_Series.Count));
// This also works.
sleep(2000);
OSC_Series.Clear;
// This does not work.
sleep(1000);
OSC_Series.Clear;
end;
显然,我很难过。
答案 0 :(得分:1)
这有点像代码正在使用一个已被破坏的对象(OSC_Series
),然后内存被重新用于其他东西。然后,当您使用对该内存的陈旧引用时,您会得到意外且不可预测的结果。
OSC_Series
免费在哪里?
我会检查所有这些地方,并确保您免费使用OSC_Series
参考后
另请注意,由于该系列由表单拥有,因此表单本身可能会在事件摧毁其拥有的组件(包括此系列)之后在事件中执行代码。
答案 1 :(得分:1)
好吧,愚蠢而不是愚蠢。
我试验了showmessage声明的位置。我发现如果该语句出现在OSC_Series.Clear语句之后,我只能避免错误。我继续移动该语句,直到调用AnalysisRefresh例程之后,该例程位于按钮的OnClick事件处理程序中。这意味着刷新,启用或更新例程中的所有代码都没有导致这种情况。
退一步,如果AnalysisRefresh例程失败,则会向用户显示一条消息。关闭该框后,调用OSC_Series.Clear。如果我通过按键盘上的SPACE或ENTER关闭该框...没有错误。如果我使用鼠标,请输入错误。
鼠标后面的图表有一个OnMouseMove事件,我在状态栏上显示鼠标位置。如果鼠标靠近绘图点,我也会显示提示。单击带有鼠标的消息框以关闭它后,将调用OnMouseMove事件,当它到达可显示提示的位置时,绘制的点将消失,并且......错误。
所以,这似乎是一个几乎随机的错误,但事实并非如此。触发器完全在其他地方。那是你我的尝试/除了块没有捕获错误。 EurekaLog正在捕捉它,但是远远不同的程序。 (Deltics的答案非常接近。)
感谢您的帮助和建议。
当有几天我可以毫无问题地推出数百行代码时,就会出现这种情况,然后会出现类似这样的事情并且花了我两天的时间。