当我尝试解组一个格式不正确的JSON对象时,我希望UnMarshall函数提供一个对象引用,但它没有。但是,当我关闭我的应用程序时,该对象会产生内存泄漏。
TMyObject = class
private
FName: String;
end;
AJSON := TJSONObject.ParseJSONValue('{ type: "MyObject.TMyObject", id: 1, fields: { FName: "David", FAge: 20 } }');
//FAge attribute don't exists in TMyObject, so it raises an exception when unmarshalling
with TJSONUnMarshal.Create() do
begin
try
Result := Unmarshal( AJSON );
//First chance exception at $77322F71. Exception class EConversionError with message 'Internal: Field FAge cannot be found in type TMyObject'. Process MyApp.exe (3056)
finally
Free();
end;
//Here the result is nil, but internally the object was created and is alive
end
function TJSONUnMarshal.Unmarshal(Data: TJSONValue): TObject;
var
Root: TJSONObject;
begin
if not (Data is TJSONObject) then
raise EConversionError.Create(SCannotCreateObject);
// clear previous warnings
ClearWarnings;
Root := TJSONObject(Data);
try
Result := CreateObject(Root)
finally
FObjectHash.Clear;
end;
end;
如果JSON对象不是预期的格式,它会引发异常,但不会破坏对象创建的引用,也不会在函数上返回它。
因此,使用我的服务器的某个人可以调用某些函数,并且没有任何警告将发送到请求的JSON格式化得很好。
我该如何处理这种情况?有一种方法可以使用相应的类来验证JSON对象吗?
ps:我正在使用Delphi XE7
答案 0 :(得分:0)
如果您创建一个Unmarshal对象并将所有对象分开处理,那么 (可能)使用
AJSON := TJSONObject.ParseJSONValue('{ type: "MyObject.TMyObject", id: 1, fields: { FName: "David", FAge: 20 } }');
try
if Assigned(AJSON) then
UnmarshalThisObject(AJSON);
finally
FreeAndNil(AJSON);
end;
procedure UnmarshalThisObject(AJSON: TJSONObject);
var
oUnMarshalObject: TJSONUnMarshal;
oUnMarshalResult: TUnmarshalType {dont know};
begin
if Assigned(AJSON) then
begin
oUnMarshalObject := TJSONUnMarshal.Create();
try
oUnMarshalResult := oUnMarshalObject.Unmarshal(AJSON);
finally
FreeAndNil(oUnMarshalResult);
FreeAndNil(oUnMarshalObject);
end;
end;
end;
希望它有所帮助。
答案 1 :(得分:0)
像Unmarshal
这样返回新创建对象的函数必须像这样实现:
function CreateObj: TObject;
begin
Result := TObject.Create;
try
// do stuff with Result
except
Result.Free;
raise;
end;
end;
如果try
中没有此类except
/ Unmarshal
块,并且我看不到要检查的代码,那么只要它引发就会泄漏。
你可以从外面做很多事情。像这样的bug无法从外部轻松修复。一旦物体泄漏,你就无法抓住它来摧毁它。
您当然应该提交质量控制报告。在短期内,您可能需要修改Unmarshal
代码并重新编译,以添加缺少的try
/ except
块
我认为处理问题的另一种方法是停止提供导致异常的此功能输入。