[英]How to free correctly a JSON object with delphi
我正在使用 Delphi Rio。
我需要创建一个 JSON。 我的代码创建了 JSON,但是当我释放 JSON 对象时我得到了一个 AV。
在我的代码中,我注意到在 js.Free 中出现了 AV,当我添加以下行时:
jaespecs:=GetEspecsFromMedico(fieldbyname('nr').AsInteger);
jstemp.AddPair('especs',jaespecs);
我的 JSON 具有以下格式:
{data:[
{
data_agenda:'23/02/67',
medicos:[
{nome:'pedro',espec:'orto',horai:'',horaf:'',especs:[]},
{nome:'pedro',espec:'orto',horai:'',horaf:'',especs:[]}
]
},
{
data_agenda:'23/02/68',
medicos:[
{nome:'pedro',espec:'orto',horai:'',horaf:'',especs:[]},
{nome:'pedro',espec:'orto',horai:'',horaf:'',especs:[]}
]
}
]
}
当我使用 ("js.Free") 释放 JSON 时,我的函数可以很好地创建 json,但 AV 除外。 这是代码:
function GetJSONPeriodo(datai,dataf: TDatetime;const med:Integer=-1;const espec:Integer=-1): string;
var i:integer;
dia:string;
js,jso,jstemp:TJSonObject;
ja,jatemp,jaespecs:TjsonArray;
vdata:TDatetime;
function GetEspecsFromMedico(med:Integer):TjsonArray;
var qry:TFDQuery;
je:TJsonObject;
begin
je:=TJsonObject.Create;
result:=TjsonArray.Create;
qry:=controller.DM.CreateQuery();
try
with qry do begin
close;
Sql.Clear;
SQl.Add('select A.nr,B.nome,A.nesp from ESP_QUE_MEDICO_TEM A');
if prepared then disconnect;
Open;
First;
while not eof do begin
je.AddPair('nome',TJsonString.create(fieldbyname('nome').AsString));
je.AddPair('nesp',TJsonString.create(fieldbyname('nesp').AsString));
result.AddElement(je);
next;
end;
end;
finally
qry.Free;
end;
end;
begin
vdata:=datai;
js:=TJSonObject.Create;
ja:=TjsonArray.Create;
try
while vdata<=dataf do begin
i:=DayOfWeek(vdata);
dia:= uppercase(formatsettings.ShortDayNames[i]);
with DM.FDQQuery do begin
Close;
SQL.Clear;
SQL.Add('Select B.nr,B.nome,A.hini,A.hfim from HORARIO_ATEND_MEDICO A');
if not prepared then prepare;
parambyname('dia').Value:=dia;
Open;
jso:=TJsonObject.Create;
jso.AddPair('data_agenda',TJSONString.Create(formatdatetime('dd/mm/yyyy',vdata)));
jatemp:=TjsonArray.Create;
while not eof do begin
jstemp:=TJsonObject.Create;
jstemp.AddPair('text',TJSONString.Create(fieldbyname('nome').AsString));
// if I get rid off the next two lines, no AV occur
jaespecs:=GetEspecsFromMedico(fieldbyname('nr').AsInteger);
jstemp.AddPair('especs',jaespecs);
jatemp.AddElement(jstemp);
next;
end;
jso.AddPair('medicos',jatemp);
ja.AddElement(jso);
end;
vdata:=vdata+1;
end;
js.AddPair('data',ja);
result:=js.ToJSON;
finally
js.Free; //I get an AV here
end;
end;
在GetEspecsFromMedico 中,您多次将相同的实例je添加到结果数组中。 当数组被释放时,该实例也被多次释放。
您需要在while not eof循环中创建一个新的je实例。
所以。 编辑您的代码。
function GetEspecsFromMedico(med: Integer): TjsonArray;
var
qry: TFDQuery;
je: TJSONObject;
begin
result := TjsonArray.Create;
qry := controller.DM.CreateQuery();
try
[...]
while not eof do
begin
je := TJSONObject.Create; // move here
je.AddPair('nome', TJsonString.Create(fieldbyname('nome').AsString));
je.AddPair('nesp', TJsonString.Create(fieldbyname('nesp').AsString));
result.AddElement(je);
next;
end;
end;
finally
qry.Free;
end;
end;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.