繁体   English   中英

如何使用delphi正确释放JSON对象

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM