Delphi-フォームのコンポーネントカウントが減少したときにどのように壊れますか

StackOverflow https://stackoverflow.com/questions/5812640

質問

以下のコードは、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 変数。
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top