Интересно, почему сортировка моего объекта на строку протекает, я пытался освободить JSONMarshal (а на самом деле также пытался освободить конвертер, создав его экземпляр), но он все еще течет? Разве не должно быть достаточно, чтобы освободить JSONMarshal?Delphi Marshalling мой объект для строк утечки, но почему?
function TPerson.ToJsonString: string;
var
JSONMarshal: TJSONMarshal;
begin
result := '';
JSONMarshal := TJSONMarshal.Create(TJSONConverter.Create);
try
Result := JSONMarshal.Marshal(self).ToString;
finally
JSONMarshal.Free;
end;
end;
Вот тестовый объект - просто сделать экземпляр TPerson (1 «) и вызовите ToJsonString - то вы увидите утечку.
unit TestObjU;
interface
uses
Classes, System.Generics.Collections, System.SysUtils,
Data.DBXJSON, Data.DBXJSONReflect, JSON,
Data.FireDACJSONReflect, FireDAC.Comp.Client, vcl.ExtCtrls,
pngimage, graphics, variants;
type
EPerson = class(Exception);
EPersonsList = class(Exception);
TGender = (Female, Male);
TPerson = class(TObject)
private
FFirstName: string;
FLastName: string;
FId: Integer;
FGender: TGender;
FModified : Boolean;
[JSONMarshalled(False)]
FPicture : TPicture;
function GetName: string;
procedure SetFirstName(const Value: string);
procedure SetLastName(const Value: string);
function GetId: Integer;
procedure SetGender(const Value: TGender);
procedure SetModified(const Value: Boolean);
public
property Id : Integer read GetId;
property Name : string read GetName;
property FirstName : string read FFirstName write SetFirstName;
property LastName : string read FLastName write SetLastName;
property Gender : TGender read FGender write SetGender;
property Modified : Boolean read FModified write SetModified;
[JSONMarshalled(False)]
property Picture : TPicture read FPicture write FPicture;
function Update : Boolean;
function Delete : Boolean;
constructor Create(AId : Integer; AFirstName, ALastName : string; AGender : TGender); overload;
destructor destroy; override;
function ToJsonString: string;
class function FromJsonString(AJSONString: string): TPerson; static;
end;
implementation
{ TPerson }
constructor TPerson.Create(AId: Integer; AFirstName, ALastName: string;
AGender: TGender);
begin
inherited Create;
FPicture := TPicture.Create;
FId := AId;
FFirstName := AFirstName;
FLastName := ALastName;
FGender := AGender;
end;
function TPerson.Delete: Boolean;
begin
Result := False;
if (FId > 0) then // if Id below zero we have a problem
begin
Result := True;
FModified := False;
end;
end;
destructor TPerson.destroy;
begin
FreeAndNil(FPicture);
inherited;
end;
function TPerson.GetId: Integer;
begin
Result := FId;
end;
function TPerson.GetName: string;
begin
Result := FFirstName + ' ' + FLastName;
end;
procedure TPerson.SetFirstName(const Value: string);
begin
FFirstName := Value;
FModified := True;
end;
procedure TPerson.SetGender(const Value: TGender);
begin
FGender := Value;
FModified := True;
end;
procedure TPerson.SetLastName(const Value: string);
begin
FLastName := Value;
FModified := True;
end;
procedure TPerson.SetModified(const Value: Boolean);
begin
FModified := Value;
end;
function TPerson.ToJsonString: string;
var
JSONMarshal: TJSONMarshal;
begin
result := '';
JSONMarshal := TJSONMarshal.Create(TJSONConverter.Create, True);
try
Result := JSONMarshal.Marshal(self).ToString;
finally
JSONMarshal.Free;
end;
end;
class function TPerson.FromJsonString(AJSONString: string): TPerson;
var
JSONUnMarshal: TJSONUnMarshal;
begin
JSONUnMarshal := TJSONUnMarshal.Create;
try
Result := JSONUnMarshal.Unmarshal(TJSONObject.ParseJSONValue(AJSONString)) as TPerson;
finally
JSONUnMarshal.Free;
end;
end;
function TPerson.Update: Boolean;
var
AStream : TMemoryStream;
begin
if (FId > 0) then // if Id below zero we have a problem
begin
AStream := TMemoryStream.Create;
try
Picture.Graphic.SaveToStream(AStream);
AStream.Position := 0; // wind back if needed
finally
FreeAndNil(AStream);
end;
end;
FModified := False;
end;
{ TPersonsList<T> }
end.
procedure TForm2.Button1Click(Sender: TObject);
var
APerson : TPerson;
begin
APerson := TPerson.Create(1, 'Donald', 'Duck', Male);
try
Memo1.Lines.Add(APerson.ToJsonString);
finally
APerson.Free;
end;
end;
Как вы обнаружили утечку? Использование FastMM? – RBA
[mcve] был бы полезен. Не может быть. Возможно, это актуально: http://qc.embarcadero.com/wc/qcmain.aspx?d=81862, и я думаю, что мы должны знать версию delphi тоже –
Я использовал только ReportMemoryLeaksOnShutdown: = True; Я посмотрю, могу ли я получить журнал FastMM, и я использую XE10 upd1 – hhaumann