2016-03-08 2 views
1

Интересно, почему сортировка моего объекта на строку протекает, я пытался освободить 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; 
+0

Как вы обнаружили утечку? Использование FastMM? – RBA

+1

[mcve] был бы полезен. Не может быть. Возможно, это актуально: http://qc.embarcadero.com/wc/qcmain.aspx?d=81862, и я думаю, что мы должны знать версию delphi тоже –

+0

Я использовал только ReportMemoryLeaksOnShutdown: = True; Я посмотрю, могу ли я получить журнал FastMM, и я использую XE10 upd1 – hhaumann

ответ

2

Маршал возвращает TJSONValue экземпляр и мне кажется, что вам нужно уничтожить этот экземпляр.

function TPerson.ToJsonString: string; 
var 
    JSONMarshal: TJSONMarshal; 
    Value: TJSONValue; 
begin 
    JSONMarshal := TJSONMarshal.Create(TJSONConverter.Create, True); 
    try 
    Value := JSONMarshal.Marshal(Self); 
    try 
     Result := Value.ToString; 
    finally 
     Value.Free; 
    end; 
    finally 
    JSONMarshal.Free; 
    end; 
end; 

Ваш метод, который работает в обратном направлении, допускает ту же ошибку. Это должно быть:

class function TPerson.FromJsonString(AJSONString: string): TPerson; 
var 
    JSONUnMarshal: TJSONUnMarshal; 
    Value: TJSONValue; 
begin 
    JSONUnMarshal := TJSONUnMarshal.Create; 
    try 
    Value := TJSONObject.ParseJSONValue(AJSONString); 
    try 
     Result := JSONUnMarshal.Unmarshal(Value) as TPerson; 
    finally 
     Value.Free; 
    end; 
    finally 
    JSONUnMarshal.Free; 
    end; 
end; 
+0

Да, вы правы, JSONvalue должно быть освобождено - это решает утечка. Спасибо – hhaumann

 Смежные вопросы

  • Нет связанных вопросов^_^