Page 1 of 1

Como libero de memoria una clase dinamica

Posted: Thu Jun 12, 2008 12:00 am
by Vladimir Zorrilla
Estimados Amigos
Usa una funcion para crear DATAfields

function TMyMSQuery( cCls ) ; return( MyGenClass( cCls, TMSQuery() ) )


Uso una variable __aHCls a la que le agrego AAdd( __aHCls, { cClsName, __nClassH } ) la clase
y su manejador pero no se como liberar esro por que cada vez que llamo a la clase
me consume recursos


static __aHCls := {}

#include "HbClass.ch"

//---------------------------------------------------------------------------//
// Generador de clases dinamicas

function MyGenClass( cClsName, FromClass )

local n, __nClassH, __odB
local cFromClass := upper( FromClass:ClassName() )

cClsName := "TMY" + Upper( if( empty( cClsName ), ;
PadL( len( __aHCls ), 7, "0" ), Alltrim( cClsName ) ) )

if ( n := AScan( __aHCls, { |aClass| aClass[ 1 ] == cClsName } ) ) == 0
_HB_CLASS cClsName
__oDb := HBClass():New( cClsName, { cFromClass } )
__oDb:Create()
__nClassH := __oDb:hClass
AAdd( __aHCls, { cClsName, __nClassH } )
else
__nClassH := __aHCls[ n, 2 ]
endif

return( __clsInst( __nClassH ) )




Ahora si creo una funcion para eliminar del __aHCls los manejadores
de la clase una vez q termino de usarla



/// eliminar de __aHCLS la clase generada

Function CloseClass( oClase )
Local n,cClsName

cClsName := "TMY" + Upper( PadL( len( __aHCls ), 7, "0" ) )

if ( n := AScan( __aHCls, { |aClass| aClass[ 1 ] == cClsName } ) ) == 0
// ya se creo la clase
else
__aHCls[ n, 1 ]:=NIL
__aHCls[ n, 2 ]:=NIL
ADEL( __aHCls , n )

endif
oClase:=NIL


return( cClsName )


Se que se crea una clase TMY00005 pero no se como liberar de memoria esta clase y su data

Posted: Thu Jun 12, 2008 7:00 am
by Antonio Linares
Vladimir,

Que yo sepa, no se ha implementado aún el borrar classes en Harbour/xHarbour.

Se podría hacer perfectamente, pero aún no se ha implementado.

Por eso una alternativa para no ir creando más y más classes es usar una sola, que simule distintas DATAs usando OnError. Revisa la clase TDataBase de FWH que usa esta técnica.

Posted: Fri Jun 13, 2008 3:21 am
by Vladimir Zorrilla
Excelente al instar al objeto con un nombe de campo que no existe como data fuerzo el flujo hacia el error y este metodo captura ese evento donde busco el numero del nombre del campo y aplico el FieldGet

Asi ni siquiera creo una data por campo y supongo que esto no debe
consumir nada de memoria o me equivoco.

METHOD OnError( uParam1 ) CLASS TMSQuery
local cMsg := __GetMessage()
local nError := If( SubStr( cMsg, 1, 1 ) == "_", 1005, 1004 )
local nField

cMsg = Upper( cMsg )
//msgalert( cMsg )

if( ( nField := ::FieldPos( cMsg ) ) != 0 )
return ::FldGet( nField )
else
_ClsSetError( _GenError( nError, ::ClassName(), cMsg ) )
endif

return nil

Posted: Fri Jun 13, 2008 8:26 am
by Antonio Linares
Asi es, no consume memoria pues es totalmente dinámico.

Tal vez no tenga la misma velocidad que una DATA real, pero evita tener que crear muchas classes.