gpt4 book ai didi

delphi - 由于事件处理中的周期,Delphi堆栈溢出

转载 作者:行者123 更新时间:2023-12-03 18:53:51 25 4
gpt4 key购买 nike

我正在处理具有两个列表框的应用程序。我用值加载两个列表框,当我继续单击列表框中的项目时,在调试时收到以下错误。



运行exe会导致应用程序关闭。有时我会收到“访问冲突”消息。

所以我该怎么做才能摆脱我的重复应用中的错误?

编辑

..

主窗体具有用于刷新所有控件的计时器
timer_RefreshCOntrol(时间间隔1)。

每当修改editBox_one时(值)
这个功能叫做

Procedure TStringSetting.SetValue (const AValue : String);
Begin
...
If FValueControl <> Nil then
Begin
FValueControl.OnChange := VoidNotifyEvent;
FValueControl.Text := NewValue;
FValueControl.OnChange := EditChange; //<--here the stackoverflow error comes....
end;
end;




Procedure EditChange (Sender: TObject);
Begin
Value := FValueControl.Text;
If Not EditIsValid then FValueControl.Font.Color := clRed
else If Dirty then FValueControl.Font.Color := clBlue
else FValueControl.Font.Color := clWindowText;

If @OldCustomEditChange <> Nil then OldCustomEditChange(Sender);
end;`


the EditChange (Sender: TObject); <--keeps geting called and the stackoverflow error comes


EditChange被分配给 FormCreate上的编辑框

编辑2

我不是原始开发人员,有时我只是处理代码,无法进行重大重构。

编辑3
调用堆栈的值是多少?


编辑4

经过@Cosmin Prund和@david之后

我得到了无限通话开始的地方

   Procedure TFloatSetting.EditChange (Sender: TObject);
Begin
SkipNextOnChange := True;
Inherited EditChange(Sender);
IfValidThenStore(FValueControl.Text);
Inherited EditChange(Sender); {<-------This is where it start}
end;


Procedure TStringSetting.EditChange (Sender: TObject);
Begin
Value := FValueControl.Text;
If Not EditIsValid then FValueControl.Font.Color := clRed
else If Dirty then FValueControl.Font.Color := clBlue
else FValueControl.Font.Color := clWindowText;

If @OldCustomEditChange <> Nil then OldCustomEditChange(Sender); {<---this keeps calling Procedure TFloatSetting.EditChange (Sender: TObject);}
end;

最佳答案

从发布的调用堆栈中可以很明显看出发生错误的原因:TStringSetting.EditChange触发TFloatSetting.EditChange,然后又触发TStringSetting.EditChange。如此循环直到所有堆栈空间都用完为止。

以下是一些提示,指出了为什么会发生这种情况,以及有关如何调试和修复它的提示:


可能在逐步更改OnChange时涉及的控件会触发Value事件处理程序。如果两个编辑器应该以两种格式显示相同的数据,并且您使用各自的OnChange事件处理程序使它们保持同步,则可能是原因。
也许您是直接从另一个调用一个事件处理程序。


调试方法:


您应该首先尝试断点解决方案,如paulsm4所建议。如果每次调用OnChange处理程序之一都发生堆栈溢出,则此解决方案将很容易起作用。
注释掉事件处理程序之一的代码。运行该程序,该错误应该不再出现。以少量(但合乎逻辑)取消注释代码,然后测试并重复。当错误再次出现时,您就知道您在资助引起错误的行。如果您自己找不到答案,请编辑问题,添加代码并标记刚发现的那行会给您带来麻烦。


如果以编程方式更改了值时,如果所使用的控件正在触发OnChange事件处理程序,则应使事件处理程序不可重入:这肯定会停止无限递归循环。我几乎总是假设当属性从代码更改时,控件会触发OnChange或等效事件,并始终使用以下类似方法保护自己免遭再次进入:

// Somewhere in the private section of your form's class:
FProcessingEventHandler: Boolean;

// This goes in your event handler
procedure TYourForm.EventHandler(Sender:TObject);
begin
if FProcessingEventHandler then Exit; // makes code non-reentrant
FProcessingEventHandler := True;
try
// old code goes here ...
finally FProcessingEventHandler := False;
end;
end;

关于delphi - 由于事件处理中的周期,Delphi堆栈溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9613659/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com