【问题标题】:JSON to StringList using Delphi Xe5使用 Delphi Xe5 的 JSON 到 StringList
【发布时间】:2013-11-08 00:20:58
【问题描述】:

我正在使用 Delphi Xe5,并且我有一个组件,它基本上使用 IDTCPCLient(套接字)与服务器通信并以 JSON 的形式检索数据。我已经为您省去了所有的连接代码等。它可以工作。返回的 JSON 也可以工作。我遇到的麻烦是将我的 JSON 转换为 StringList,然后我用它来将值列表写入列表框并将其余 JSON 数据对象存储在 TSTrings OBjects 属性中。

我发生了许多有趣的事情。

1.) 我一辈子都无法让 List 属性正常工作。我使用这个列表来存储我的 JSON。一个字符串值,然后是列表中每个项目的整个对象。你会注意到在 JSONToStringList 方法中,我清除了字符串列表(它被注释掉了,因为当它不是时,我的程序挂起)

2.) 对于需要的多个 JSON 集多次调用该方法后,我的列表中出现重复值

TConnector = class(TComponent)
  private
    { Private declarations }
    FList: TStrings; 
    procedure SetList(const Value: TStrings); 
  protected
    { Protected declarations }
  public
    { Public declarations }
    Constructor Create( AOwner : TComponent ); override;
    Destructor Destroy; Override;
    Procedure GenerateJSON;
    Procedure JSONToStringList(aJSonKey: String);
  published
    { Published declarations }
    property List: TStrings Read FList Write SetList; 

  end;


Constructor TConnector.Create(AOwner: TComponent);
begin
  inherited;
  FList:= TStringList.Create(True);
end;


destructor TConnector.Destroy;
begin
  if FList <> nil then
   FreeAndNil(FList);
  inherited;
end;

Procedure TConnector.GenerateJSON;
begin
if ResponseStream<>nil then
  Begin
  FreeAndNil(ResponseJSON_V);
  ResponseJSON_V := TJSONObject.ParseJSONValue(StreamToArray(ResponseStream),0) as TJSONValue;
  End;
end;

procedure TConnector.JSONToStringList(aJSonKey: String);
Var
  zLJsonValue  : TJSONValue;
  zLJSONArray: TJSONArray;
  zLJsonObject : TJSONObject;
  zI           : Integer;
begin
  if ResponseJSON_V is TJSONArray then
  begin
    zLJSONArray:= ResponseJSON_V as TJSONArray;
    zLJsonObject := zLJSONArray.Get(0) as TJSONObject;
  end
  else
  if ResponseJSON_V is TJSONObject then
  begin
    zLJSONArray:= nil;
    zLJsonObject := ResponseJSON_V as TJSONObject;
  end
  else
    Exit;
  if zLJSONArray<>nil then
  begin
     ***//FList.Clear;***
    for zLJsonValue in zLJSONArray do
    begin
      zLJsonObject := zLJsonValue as TJSONObject;
      for zI := 0 to zLJsonObject.Size-1 do
      begin
        if zLJsonObject.Get(zI).JsonString.Value = aJSonKey then
        begin
          FList.AddObject(zLJsonObject.Get(zI).JSONValue.Value, zLJsonObject);
        end;
      end;
    end;
  end
  else
  begin
    FList.Clear;
    for zI := 0 to zLJsonObject.Size-1 do
      begin
        if zLJsonObject.Get(zI).JsonString.Value = aJSonKey then
        FList.AddObject(zLJsonObject.Get(zI).JSONValue.Value, TJSONPair(zLJsonObject.Get(zI)));
      end;
  end;
end;

我希望这一切都可以理解。如果您需要查看更多信息,请告诉我。请随时纠正您在我的代码中看到的任何错误。我一直在学习:) - 谢谢你的帮助

【问题讨论】:

标签: json delphi delphi-xe5


【解决方案1】:
  1. 如果 FList.Clear 挂起,则很可能是内存损坏问题。我怀疑的前两件事是您没有调用构造函数,或者内存的一部分已被其他内容覆盖。

  2. 列表中的重复值是否是由于您注释掉了 FList.Clear 造成的。无论如何,我建议使用调试器来查看列表中的内容或记录添加到列表中/从列表中删除的所有内容。这应该让您了解列表中不需要的值的来源。

  3. 作为一般建议,您无需在释放对象之前检查对象是否不为零。无论如何,检查都是在 Free(或 FreeAndNil 的 Free 部分)中进行的。

【讨论】:

  • 感谢您的回复。 1.) 我同意,我相信这就是问题所在,但我找不到它 2.) 如上所述,只有当我取消注释 FList 时它才会挂起,而当它被注释掉时,我会得到重复价值观 :) 3.) 感谢您的建议
  • 你看过 RestClient 库的东西吗?这可能会有所帮助。
【解决方案2】:

事实证明,FList 属性不应该被发布,而是被公开。这使得由于列表仅在运行时填充和清空,而不是在设计时。

TLiveConnector = class(TComponent)
  private
    { Private declarations }
  protected
    { Protected declarations }
  public
    { Public declarations }
     List: TStrings;  
  published
  end;

不知道为什么会这样,但它现在似乎工作得很好

调用 List.Clear 而不是 FList.Clear;

【讨论】:

    【解决方案3】:

    你的代码不能工作......你定义了一个名为“aJSonKey”的参数,你在过程中称之为“ResponseJSON_V”。

    此外,当没有以这种方式调用的属性时,您将此“ResponseJSON_V”称为 GenerateJSON proc。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多