Ver Mensaje Individual
  #4  
Antiguo 20-01-2015
orihuela orihuela is offline
Registrado
NULL
 
Registrado: ene 2015
Posts: 5
Reputación: 0
orihuela Va por buen camino
Cita:
Empezado por Neftali Ver Mensaje
Eso es una asignación de punteros. Al hacerlo SQL debería estar sin crear (apuntando a nil), pues si lo estuviera sí que perderías acceso a la memoria apuntada y por lo tanto tendrías pérdida de memoria.

Al liberar el Query, la variable SQL no se apunta a nil, a no ser que lo hagas manualmente. Si intentas hacer algo con va variable SQL seguramente obtendrás un access Violation, pues esa memoria a la que apunta ya ha sido liberada.
Eso es lo que en primera instancia yo creia, que es una asigancion de punteros, pero entonces no entiendo algunos comportamientos: sea el siguiente ejemplo:

Código Delphi [-]
  procedure TCliente.ListarClientes (var SQL: TSQLQUERY; filtro: TDictionary<String,String>;orden: TDictionary<String,String>);
var modelocliente: TModeloCliente;
    sqlaux:tsqlquery;


begin
  modelocliente:=TModeloCliente.Create;
  freeandnil(sql);
  SQL:= modeloCliente.ListarClientes(filtro,orden);
  sqlaux:=SQL;
  showmessage(sqlaux.Text);
  freeandnil(sqlaux);
  Showmessage(SQL.Text);
end;

Si realmente es una asigancion de punteros, el ultimo showmessage deberia lanzarme un acess violation puesto que se ha liberado el espacio al que apunta, y para mi sorpresa me muestra el showmessage.
¿Porque?,¿Tal vez sea por como se gestiona la memoria en android?.


De todas maneras así ha quedado el código final, que creo que es lo que te entendí. (Se han añadido las variables reales de la funcion):

<Controlador cliente, Procedimiento ListarClientes >

Código Delphi [-]

procedure TCliente.ListarClientes (var SQL: TSQLQUERY; filtro:  TDictionary<String,String>;orden:  TDictionary<String,String>);
var modelocliente: TModeloCliente;

begin
  
  
  modelocliente:=TModeloCliente.Create;
  // Libero el espacio al que apuntaba anteriomente SQL.
  freeandnil(sql);
  // Se asigna SQL el nuevo Tsqlquery.
  SQL:= modeloCliente.ListarClientes(filtro,orden);

end;




type
  TModeloCliente = class(TModelo) 
  private
  {}
  protected
    { Declaraciones protegidas de la clase }
  public
    function ListarClientes( filtro:TDictionary<String,String>;orden:TDictionary<String,String> ):TSQLQuery;
    function ConsultarCliente( codigo: string ): TSQLQuery;
    function  ObtenerRecargo(codigo:string):string;
    function  ConsultarClientesCompletable(codigo:string): TSQLQuery;
    function  Obtenerrutas():TSQLQuery;
  published
    { Declaraciones publicadas de la clase }
  end;


var cdatos: TSQLConnection;
    QueryGlobal: integer;




type
  TModelo = class(TObject) 
  private
   //esta variable es la que se manda cargada con la consulta pertimente, en listarclientes 
  SQL: TSQLQuery;
  protected
    function DevolverBD():TSQLQuery;
  public
    constructor Create;overload;
    Destructor  Destroy; override;

    procedure EjecutarInstruccion( instruccion:String );
    procedure EjecutarModificacion( instruccion:String );
    function  Genera_Sentencia_Insert(SQL:TDataSet;nombre:String;Campos:Array of String):TStrings;
    function Genera_Sentencia_Update(SQL:TDataSet;nombre,Condicion:String;Campos:Array of String):TStrings;
    procedure EjecutarInsert(nombre:string;Campos:array of string;Valores: Array of variant);
    procedure EjecutarUpdate(nombre,condicion:string;Campos:array of string;Valores: Array of variant);


  published
    { Declaraciones publicadas de la clase }
  end;

< os pongo el codigo del constructor y del destructor, por sí aclara mas la situación >

Código Delphi [-]
 constructor TModelo.Create;
 begin
  inherited;

  if ( cdatos = nil ) then
  begin
  cdatos:=TSQLConnection.Create(Application);
  cdatos.DriverName:='SQLite';
  cdatos.ConnectionName:='cdatos';
  cdatos.Name:='cdatos';
  cdatos.KeepConnection:=True;
  cdatos.LoginPrompt:=False;
  
  cdatos.Params.Add('DriverName=SQLite');
  cdatos.Params.Add('DriverUnit=Data.DbxSqlite');
  cdatos.Params.Add('DriverPackageLoader=TDBXSqliteDriverLoader,DBXSqliteDriver170.bpl');
  cdatos.Params.Add('MetaDataPackageLoader=TDBXSqliteMetaDataCommandFactory,DbxSqliteDriver170.bpl');
  cdatos.Params.Add('FailIfMissing=True');
  cdatos.Params.Add('Database='+TPath.Combine(TPath.GetSharedDocumentsPath, 'Cdatos.s3db'));
  
  cdatos.Connected:=True;
  QueryGlobal:=0;
  end;

  SQL:=TSQLQuery.Create(nil);
  SQL.SQLConnection:=cdatos;
  SQL.Name:='name'+ IntToStr(QueryGlobal);
  QueryGlobal := QueryGlobal + 1;

 end;


destructor TModelo.Destroy;
begin


    //freeandnil(sql);
    
// actualmente la sentecia freeandnill(sql) esta comentada. por lo que  dijistes de que 
//si liberamos esta variable, cuando se destrulla el  modelo, las demas asignaciones que se han 
// hecho de esta variable  deberian fallar, puesto que a lo que apuntan estaria liberado. aunque la practica no lo confirme.

  
  inherited;
end;

No se si me habre explicado bien puesto que el tema no es facil de explicar, pero si necesitas de alguna función mas para su compresión por favor solicitamelo. Un saludo y muchisimas gracias

Última edición por Neftali [Germán.Estévez] fecha: 20-01-2015 a las 18:11:59. Razón: Poner tags al código
Responder Con Cita