Cita:
Empezado por Neftali
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;
freeandnil(sql);
SQL:= modeloCliente.ListarClientes(filtro,orden);
end;
type
TModeloCliente = class(TModelo)
private
protected
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
end;
var cdatos: TSQLConnection;
QueryGlobal: integer;
type
TModelo = class(TObject)
private
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
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
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