Hola a todos, yo creo que tengo el mismo error... y me estoy volviendo LOOOOCO y no logro resolverlo. Seguramente sea una tontería, pero es que NO LO LOGRO.
Explico mi caso.
Estoy haciendo el modelo de negocios de un hotel, el cual explico brevemente:
- Clase
THabitaciones (hereda de TComponent), que es básicamente una lista con componentes THabitacion (o TBaseHabitacion).
- Clase
THabitacion (hereda de TComponent), representa una habitación como tal. Está formada basicamente por dos partes, Un componente GUI: TBaseGUI y un objeto Info: TBaseInfo.
- Clase
TBaseGUI (hereda de TComponent), es el tope de una jerarquia para la representación gráfica de las habitaciones.
- Clase
TBaseInfo (hereda de TObject), es el tope de una jerarquia para la información de las habitaciones. Va variando según el tipo en tiempo de ejecución.
En el form principal hago lo siguiente en el evento OnClose:
Código:
...
TiposHabitaciones.Free;
Habitaciones.Free;
La idea es:
1.- Destruir
Habitaciones: THabitaciones (cuando creo una Habitacion: THabitacion hereda de TComponent y el Owner es Habitaciones, con lo cual automáticamente se liberan todas las THabitacion cuyo Owner sea Habitaciones).
2.- Cuando se destruye una
Habitacion: THabitacion, básicamente tengo que destruir la
Info pues hereda de TBaseInfo que a su vez hereda de TObject. GUI no hay que destruirlo, pues se autodestruye porque tiene como Owner la Habitacion
3.- Cuando se destruye un
GUI: TGUIHab, debo liberar el bitmap.
A continuación pondré los métodos de destrucción de las clases en ese orden:
1.- Destrucción de
Habitaciones: (en realidad no hago nada salvo Lista.Clear y Lista.Free).
Código:
Debug('THabitaciones.Destroy: ComponentCount:' + IntToStr(ComponentCount));
Debug('THabitaciones.Destroy: FLista.Count:' + IntToStr(FLista.Count));
for i := 0 to FLista.Count -1 do
begin
H := ItemsByPos[i];
if Assigned(H) then
begin
if H.Owner <> nil then
Debug(H.Caption + ' Owned by: ' + TComponent(H.Owner).Name);
// H.FreeInfo;
// H.FreeGUI;
// H.Free;
end;
// Lista.Objects[i].Free;
end;
Lista.Clear;
Debug('THabitaciones.Destroy: ComponentCount:' + IntToStr(ComponentCount));
Lista.Free;
Debug('La lista interna ha sido liberada');
inherited Destroy;
2.- Destrucción de
Habitacion: Tengo qeu destruir sólo la Info (pero está comentado, pues sospecho que me da error en el Assigned(Info)) pues el GUI tiene como Owner la Habitación y se destruirá solo.
Código:
Debug(Caption + ': THabitacion.Destroy: ComponentCount:' + IntToStr(ComponentCount));
if Assigned(Info) then
begin
Debug(Caption + ': TBaseHab.Destroy - assignado. Tipo:' + Info.ClassName);
// FreeInfo;
// FreeGUI;
end
else
Debug(Caption + ': TBaseHab.Destroy - no assignado');
Debug(Caption + ': THabitacion.Destroy: ComponentCount:' + IntToStr(ComponentCount));
inherited Destroy
3.- Destrucción de
GUI.
Código:
if Assigned(Owner) then
begin
Debug('Liberando bitmap de GUI de la habitacion: ' + TComponent(Owner).Name);
FreeResources;
end;
Debug('TGUIHabIcon: ComponentCount=' + IntToStr(ComponentCount));
//TODO: LLamar al heredado?
La destrucción de
Info no hace nada salvo llamar al heredado.
Al cerrar la aplicación obtengo un precioso mensaje
: "Invalid pointer operation." (EInvalidPointer)
Alguien me puede echar una mano con esto, por favor.
Le estaré muy agradecido, pues no logro detectar el error... Creo que falla en el if Assigned(Info) de THabitacion.Destroy, pero no estoy seguro y además no sé cómo resolverlo.
Muchas gracias de antemano y disculpen por el mensaje tan largo.
PD: A continuación adjunto la pila, por si pueda ser útil
.
------------------------------------------------------------------------------------------------
|Address |Module |Unit |Class |Procedure/Method |Line|
------------------------------------------------------------------------------------------------
|40003364|rtl90.bpl |System.pas | |Error | |
|400031AB|rtl90.bpl |System.pas | |_FreeMem | |
|40003198|rtl90.bpl |System.pas | |_FreeMem | |
|40005DBE|rtl90.bpl |System.pas | |_ClassDestroy | |
|40005DBC|rtl90.bpl |System.pas | |_ClassDestroy | |
|01658F68|CoreClassHab.bpl|UCGUIHab.pas |TGUIIcon |Destroy |127 |
|4003D718|rtl90.bpl |Classes.pas |TComponent |DestroyComponents | |
|4003D518|rtl90.bpl |Classes.pas | |TComponent | |
|01654CD6|CoreClassHab.bpl|UCHabitaciones.pas|TBaseHabitacion|Destroy |195 |
|77D2F3DE|user32.dll | | |SendMessageA | |
|77D2F39A|user32.dll | | |SendMessageA | |
|0067455A|vcl90.bpl |Comctrls.pas |TCustomListView|Scroll | |
|40006B58|rtl90.bpl |System.pas | |_LStrArrayClr | |
|003F203E|CoreLog.bpl |ULog.pas | |Log |64 |
|4003D718|rtl90.bpl |Classes.pas |TComponent |DestroyComponents | |
|4003D518|rtl90.bpl |Classes.pas | |TComponent | |
|01655442|CoreClassHab.bpl|UCHabitaciones.pas|THabitaciones |Destroy |429 |
|400059D4|rtl90.bpl |System.pas |TObject |Free | |
|400059CC|rtl90.bpl |System.pas |TObject |Free | |
|01654433|CoreClassHab.bpl|UClassObjects.pas | |CoreClassHabDestroy |30 |
|01654424|CoreClassHab.bpl|UClassObjects.pas | |CoreClassHabDestroy |29 |
|01715794|CoreMain.bpl |UPrincipal.pas |TFrmPrincipal |FormClose |357 |