Club Delphi  
    Paypal   FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Coloboración Paypal con ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 29-06-2005
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 30
jachguate Va por buen camino
Cool

Cita:
Empezado por ingel
Estas querys se liberan al liberar el form uUtiles ? (lo que se hace al cerrar la aplicacion) con lo cual se estarian creando cientos de querys sin liberar... o se libera cuando devuelve la llamada que le hizo algun form ?
Pero... esta decisión no la toma nadie por vos... que sos quien lo decide.

Si no los estas liberando, al ser propiedad de Application, se liberarán hasta le final de la ejecución, cosa que no me parece adecuada para la mayoría de los casos. En todo caso, quien sabe lo que pretende con esto y las necesidades específicas del programa sos vos, o al menos debieras saberlo..

En general es conveniente liberar la memoria tan pronto como el objeto deje de usarse. Así, si una función devuelve un TQuery, lo ideal sería algo como:

Código Delphi [-]
Function UnQuery(Parametros : TipoParametros) : TQuery;
Begin
  result := TQuery.Create(nil);
  result.HagoLoQueTengoQueHacer;
end;

Procedure TForm1.Button1Click(Sender : TObject);

Begin
  with UnQuery(Parametros) do
    try
      ProcesarElQuery;
    finally
      Free; // Libero el query
    end;
end;

//o bien:

Procedure TForm1.Button2Click(Sender : TObject);

Var
  Query : TQuery;

Begin
  Query := UnQuery(Parametros);
  try
    ProcesarElQuery(Query);
  finally
    Query.Free;
  end;
end;

{ si el uso escapa a un procedimiento o función, se puede guardar 
una referencia en el formulario y destruirlo cuando sea conveniente, 
por ejemplo en el evento OnDestroy del formulario }
Type
  TForm1 = class(TForm)
    { Lo generado por delphi }
  private
    FQueryUno : TQuery;
    // otros mienbros, métodos y/o propiedades
  end;

Procedure TForm1.Button3Click(Sender : TObject);

Begin
  if not assigned(FQueryUno) Then
    FQueryUno := UnQuery(Parametros);
  FQueryUno.First; 
  etcetera;
end;

Procedure TForm1.Form1Destroy(Sender : TObject);

Begin
  if assigned(FQueryUno) Then
    FQueryUno.Free;
end;

{ por último, se puede pasar una referencia al objeto que se quiere
  dejar como propietario del query dentro de los parámetros de 
  la función que lo crea, para delegar su destrucción al mecanismo
  de liberación automática de memoria de este objeto }

Procedure TForm1.ButtonYaPerdiLaCuentaClick(Sender : TObject);

Var
  Query : TQuery;

Begin
  Query := UnQuery(Self, OtrosParametros);
  // no hace falta liberar el query, porque self será el owner.
end;


Cita:
Empezado por roman
pd: traducción de términos con dedicatoria a jachguate

¿hay algo malo en mi forma de traducir los términos?
__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate
Responder Con Cita
  #2  
Antiguo 29-06-2005
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por jachguate
¿hay algo malo en mi forma de traducir los términos?
Me refería a esto

-------------------

Normalmente no es buena idea hacer funciones que regresen objetos creados por ellas mismas precisamente porque es difícil dar seguimiento a cuando deben destruirse.

Sin embargo, si esto es absolutamente necesario yo optaría por el uso de interfaces para que la liberación de memoria sea automática.

La idea sería algo así:


Código Delphi [-]
type
  IQueryHolder = interface
    function GetQuery: TQuery;
    property Query: TQuery read GetQuery;
  end;

  TQueryHolder = class(TInterfacedObject, IQueryCreator)
  var
    FQuery: TQuery;

  public
    constructor Create(AQuery: TQuery);
    destructor Destroy; override;

    function GetQuery: TQuery;
  end;

  implementation

  constructor TQueryHolder.Create(AQuery: TQuery);
  begin
    FQuery := AQuery;
  end;

  destructor TQueryHolder.Destroy;
  begin
    FQuery.Free;
    inherited;
  end;

  function TQueryHolder.GetQuery: TQuery;
  begin
    Result := FQuery;
  end;
end.

La interfaz IQueryHolder simplemente mantiene una referencia a un objeto Query. La clase TQueryHolder implementa esta interfaz. Dado que desciende de TInterfacedObject, su destructor será llamado en cuanto se pierda la última referencia a la interfaz y este destructor se encarga de liberar al objeto Query.

Para usar esta interfaz, la función UnQuery descrita por jachguate se debe modificar así:


Código Delphi [-]
function UnQuery(parámetros): IQueryHolder;
var
  Query: TQuery;

begin
  Query := TQuery.Create(nil);
  { pasar parámetros }
  Result := TQueryHolder.Create(Query);
end;

Y para usar el resultado se haría así:


Código Delphi [-]
var
  QueryHolder: IQueryHolder;

begin
  QueryHolder := UnQuery(parámetros);

  QueryHolder.Query.Open;
end;

Como dije antes, Sin importar dónde esté declarada la variable QueryHolder, el objeto Query que contiene se liberará en cuanto se pierda la última referencia.

// Saludos
Responder Con Cita
  #3  
Antiguo 29-06-2005
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 30
jachguate Va por buen camino
Cool

Cita:
Empezado por roman
Me refería a esto
Lo siento... no habia captado el asunto... pero efectivamente me convenzo mas cada vez de que algo tenes que ver en la traducción de libros..

Cita:
Empezado por roman
Sin embargo, si esto es absolutamente necesario yo optaría por el uso de interfaces para que la liberación de memoria sea automática.
Es simplemente una idea genial... gracias por compartirla!

Cita:
Empezado por Delphi help (f1)
TInterfacedObject serves as a convenient base class for classes that implement interfaces because it implements the methods of IInterface. TInterfaceObject descendants use the IInterface reference-counting methods to handle lifetime management. That is, when the reference count on a TInterfaceObject descendant drops to zero, the object is automatically freed.
Hasta luego.

__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate
Responder Con Cita
  #4  
Antiguo 29-06-2005
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Los puristas dicen que las interfaces no se hicieron para implementar un recolector de basura. Pero como a mi esto me tiene sin cuidado se puede incluso ir más lejos. En lugar del QueryHolder se hace una interfaz que "publique" los métodos y propiedades principales del objeto Query:


Código Delphi [-]
type
  IQuery = interface
    function ParamByName(const Value: String): TParam;
    function FieldByName(const FieldName: string): TField;

    procedure Open;
    procedure ExecSQL;
  end;

  TQueryObject = class(TInterfacedObject, IQuery)
  private
    FQuery: TQuery;

  public
    constructor Create;
    destructor Destroy; override;

    { IQuery }
    (*
      La clase implementa estas funciones simplemente delegándolas
      a su objeto privado FQuery. Por ejemplo:

      ParamByName --> Result := FQuery.ParamByName(param);
    *)
    function ParamByName(const Value: String): TParam;
    function FieldByName(const FieldName: string): TField;

    procedure Open;
    procedure ExecSQL;
  end;

implementation

constructor TQueryObject.Create;
begin
  FQuery := TQuery.Create;
end;

destructor TQueryObject.Destroy;
begin
  FQuery.Free;
  inherited;
end;

function UnQuery(parámetros): IQuery;
begin
  Result := TQueryObject.Create;
  Result.ParamByName(param).AsXXX := param;
end;

end.

Y se usaría simplemente así:

Código Delphi [-]
var
  Query: IQuery;

begin
  Query := UnQuery(parámetros);
  Query.Open;
end;

De esta manera, el código que use lo devuelto por funciones como UnQuery se ve igual que si se hubiera usado un TQuery directamente.

// Saludos
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


La franja horaria es GMT +2. Ahora son las 15:59:21.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi