Tengo un error en el tiempo de ejecución que ocurre en el rtl Flujo de un formulario, lo que hace que se levante una excepción EClassNotFound, mientras hago TReader.ReadRootComponent. El mensaje de error particular es "Class not found TActionList".¿Qué significa realmente un EClassNotFound generado en tiempo de ejecución cuando la clase en cuestión está allí en tiempo de compilación y enlace, y explícitamente en el código?
Lo que es extraño es:
- Mi forma principal utiliza la lista Acción.
- Por diversión, agregué ActnList.pas (desde la carpeta de origen de VCL) a mi proyecto, para tratar de solucionarlo.
Esto me sucede al crear una instancia de un formulario que tenía trabajando hasta hace unos minutos. El cambio que hice fue en un código de subframe: eliminé todo su código de sección de implementación con un marcador ifdef, porque estoy burlando algunos fotogramas, para pruebas unitarias y prototipos.
Intenté agregar la clase de lista de acciones al proyecto, y probé con y sin varias opciones de compilación y enlace, y aún así, sigo recibiendo esta excepción. Obviamente, algo raro está sucediendo. Debe haber otra forma extraña de tener este problema.
De hecho, parece que pasa algo realmente extraño. Cuando se eleva este error, me sale el siguiente pila de llamadas:
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)
Parece que la nula es intencional, en TReader.ReadDataInner (Instancia: TComponent):
while not EndOfList do ReadComponent(nil);
Actualización: Creo la respuesta a esta pregunta es comprender los "contextos de serialización" como lo ha mencionado Mason. Y, es hora de admitir mi propia estupidez: eliminé el padre del marco del proyecto, sin darme cuenta de que era el padre del marco. Me di cuenta de que faltaba anulando la declaración de tipo para TMyFrameParent
como TMyFrameParent = class(TFrame)
, y esto a su vez conduce a la condición en cuestión. Dejaré la pregunta aquí porque creo que en el futuro podría ser muy útil notar cuándo se produce esta excepción en casos arcanos y cómo solucionarla. En particular, Mason tiene información muy interesante sobre los "contextos de serialización" y cómo se aplican a la búsqueda de nombres de clase.
El nil solo le indica a ReadComponent que crea una nueva instancia en lugar de leer en una existente. –