Delphi-フォームのコンポーネントカウントが減少したときにどのように壊れますか
-
25-10-2019 - |
質問
以下のコードは、Toolbar2000から再現されています。これは、ツールバーの位置を読み取り、INIファイルからドック状態を読み取るルーチンの一部です。初期化中にこのルーチンを呼び出します。以下のこのコードは、メインフォームのすべてのコンポーネント(OwnerComponent)を繰り返し、見つけたツールバーの設定をロードします。
for I := 0 to OwnerComponent.ComponentCount-1 do begin
ToolWindow := OwnerComponent.Components[I]; // <------------------------
....
この繰り返しには時間がかかります(秒 - フォームに1500個のコンポーネントがあります)。表示されているポイントで範囲エラーが発生します。このループが実行されている間、1つ以上のアイテムがメインフォームのコンポーネントから削除されていることを確認しました。そのため、最終的にループはアレイの端を過ぎて1つにアクセスしようとします(おそらくこれをコーディングする方が良いでしょう。これを防ぐための「ダウントゥダウン」フォーループ)。
とにかく、メインフォームがコンポーネントを失っている場所を見つける必要があります。これを行う方法に関するDelphi 2006のデバッグのヒントを私に教えてもらえますか?私のプログラムのこの時点で、メインフォームコンポーネントが解放されるとは思わないでしょう。
アップデート
設計時にツールバーのデフォルトのドックポジションを再配置したとき、他のツールバーが入っていたドックサイトではなく、別のツールバーに不注意にドッキングしたことがわかりました。ツールバーを削除して問題を修正しました。代わりにドッキングしてドックに追加しました。したがって、問題を引き起こした取り決めは次のとおりです。
Dock
Toolbar 1
Control 1
Control 2
Toolbar 2
Control 3
Control 4
そして、修正はそのようにそれらを配置することでした:
Dock
Toolbar 1
Control 1
Control 2
Toolbar 2
Control 3
Control 4
ただし、TB2Kコードのバグを指していますが、ネストされたツールバーを処理できるはずだと思います。
解決
Lievenの回答に加えて、DEBUG DCUを使用して、ループを入力する直前にtcomponent.destroyにブレークポイントを設定することもできます。
どちらの場合も、コールスタックを調べて、カウントするコール/変更がどこから来ているかを確認する必要があります。
ブレークポイントに関する非常に興味深い記事は、キャリージェンセンによって書かれました。 http://caryjensen.blogspot.com/2010/08/breakpoints-with-side-effects.html
他のヒント
追加する必要があります データブレークポイント で @Self.FComponents.FCount
カウントが変更されるたびに壊れる。
ComponentCount
値を返すプロパティですGetComponentCount
GetComponentCount
戻り値FComponents.Count
.FComponents
aですTList
プライベートがあるインスタンスFCount
変数。