我正在开发一个DElphi FMX项目,我向REST后端提出了很多请求。
我正在使用一个TRESTClient,并且每次我要求时都动态创建TRESTRequest,我的计划是让它进行多线程以使UI更具响应性。
我已经创建了一个名为DoRequest的函数,它执行实际请求,看起来像是这样的:
Function TFormMain.Dorequest(Meth:TRESTRequestmethod;Url,RequestBody:String;
Var Respons: TCustomRESTResponse):Boolean;
Var
par: TRESTRequestParameter;
Req : TRESTRequest;
begin
Req := TRESTRequest.Create(RESTClient);
With Req do
try
if RequestBody<>'' then
begin
Params.Clear;
par := Params.AddItem('body',RequestBody);
par.ContentType := ctAPPLICATION_JSON;
par.Kind := pkREQUESTBODY;
end;
Method := Meth;
Resource := Url;
Execute;
Respons := Response;
Result := Respons.StatusCode In [200,201];
finally
Req.Free; // <-Error here
end;
end;
我称之为:
procedure TFormUser.Button1Click(Sender: TObject);
Var
Respons: TCustomRESTResponse;
begin
If DoRequest(rmPOST,CreateUserUrl,JSON,Respons) then
begin
ShowMessage('User '+EdEmail.Text+' created');
ModalResult := MrOk;
end
但是,在释放Req,我的TRESTRequest时,我收到了Acces违规行为。
我发现这是因为TCustomRESTResponse Respons只是指向放置Req.Response的内存的指针,因此释放Req也会破坏响应。
我的问题是:如何在Req被释放后复制Req.Response?
我尝试过Respons.Assign(响应),但它给出了一个相当奇怪的错误:“无法将TCustomRESTResponse分配给TFormMain”
我是以错误的方式做到这一点,还要记住我希望实际的要求是另一个步骤吗?
迈克尔
答案 0 :(得分:1)
当您没有将自己的TRESTResponse链接到客户端时,客户端将创建自己的TRESTResponse并释放它。如果您创建自己的TRESTResponse并分配它,客户端将不管它,您可以随时释放它。
也就是说,就像我在评论中提到的那样,我认为最好让线程处理反序列化的反序列化,让它传递一个更通用的类或记录来保存相关信息(value object,如果你进入那个),而不是绕过特定的TRESTResponse。