フォームのrtlStreamingでランタイムエラーが発生し、TReader.ReadRootComponentの実行中に例外EClassNotFoundが発生しました。特定のエラーメッセージは「ClassnotfoundTActionList」です。
奇妙なことは:
- 私のメインフォームはアクションリストを使用しています。
- 楽しみのために、ActnList.pas(VCLソースフォルダーから)をプロジェクトに追加して、修正を試みました。
これは、数分前まで作業していたフォームをインスタンス化するときに発生します。私が行った変更は、いくつかのサブフレームコードにありました。ユニットテストとプロトタイプのために、いくつかのフレームをモックアップしているため、ifdefマーカーを使用してすべての実装セクションコードを削除しました。
プロジェクトにアクションリストクラスを追加しようとしましたが、さまざまなコンパイラとリンクオプションがある場合とない場合がありましたが、それでもこの例外が発生します。明らかに奇妙なことが起きています。この問題を解決するには、別の奇妙な方法があるはずです。
実際、本当に奇妙なことが起こっているようです。このエラーが発生すると、次の呼び出しスタックが発生します。
rtl.Classes.ClassNotFound('TActionList')
rtl.Classes.TReader.FindComponentClass(???)
rtl.Classes.FindExistingComponent
rtl.Classes.TReader.ReadComponent(nil) /// NIL!? WHAT!!!!!
rtl.Classes.TReader.ReadDataInner(???)
rtl.Classes.TReader.ReadData(???)
rtl.Classes.TComponent.ReadState(???)
vcl.Controls.TControl.ReadState(???)
vcl.Controls.TWinControl.ReadState($60B9CF0)
vcl.Forms.TCustomForm.ReadState(???)
rtl.Classes.TReader.ReadRootComponent($606EB90)
rtl.Classes.TStream.ReadComponent($606EB90)
rtl.Classes.InternalReadComponentRes(???,???,$606EB90)
rtl.Classes.InitComponent(TComplexFormContainingFrames)
TReader.ReadDataInner(Instance:TComponent)では、nilは意図的なもののようです。
while not EndOfList do ReadComponent(nil);
更新:この質問に対する答えは、メイソンが述べたように「シリアル化コンテキスト」を理解することだと思います。そして、私自身の愚かさを認める時が来ました。私は、フレームの親であることに気づかずに、プロジェクトからフレームの親を削除しました。TMyFrameParent
asの型宣言をスタブすることで欠落を回避しましたTMyFrameParent = class(TFrame)
。これにより、問題の条件が発生します。この例外が難解なケースでいつ発生するか、およびそれを修正する方法に注意することは将来本当に便利かもしれないと思うので、ここに質問を残します。特に、Masonは、「シリアル化コンテキスト」と、それらがクラス名検索にどのように適用されるかについて、非常に興味深い情報を持っています。