2016-01-09 37 views
8

"Model Delphi'de Daha Fazla Kodlama" adlı bir kitapçığı okuyorum. Öğeleri öğrenmeye çalışıyor. Kodumu küçük birime indirdim. ReportMemoryLeaksOnShutDown := True; kullanıyorum ve yanlış kod bana bir bellek sızıntısı oluşturuyor. Neden oluyor ve nasıl düzeltebilirim?Fabrika kalıbı, bellek sızıntısı

unit Unit2; 

interface 

uses 
    Generics.Collections, System.SysUtils; 

type 
    TGatewayTpe = (gtSwedbank, gtDNB); 

type 
    TBaseGateway = class 

    end; 

type 
    TSwedbankGateway = class(TBaseGateway) 
    end; 

type 
    TGatewayFunction = reference to function: TBaseGateway; 

type 
    TGatewayTypeAndFunction = record 
    GatewayType: TGatewayTpe; 
    GatewayFunction: TGatewayFunction; 
    end; 

type 
    TGatewayFactory = class 
    strict private 
    class var FGatewayTypeAndFunctionList: TList<TGatewayTypeAndFunction>; 
    public 
    class constructor Create; 
    class destructor Destroy; 
    class procedure AddGateway(const AGatewayType: TGatewayTpe; 
     const AGatewayFunction: TGatewayFunction); 
    end; 

implementation 

class procedure TGatewayFactory.AddGateway(const AGatewayType: TGatewayTpe; 
    const AGatewayFunction: TGatewayFunction); 

var 
    _GatewayTypeAndFunction: TGatewayTypeAndFunction; 
begin 
    _GatewayTypeAndFunction.GatewayType := AGatewayType; 
    _GatewayTypeAndFunction.GatewayFunction := AGatewayFunction; 

    FGatewayTypeAndFunctionList.Add(_GatewayTypeAndFunction); 
end; 

class constructor TGatewayFactory.Create; 
begin 
    FGatewayTypeAndFunctionList := TList<TGatewayTypeAndFunction>.Create; 
end; 

class destructor TGatewayFactory.Destroy; 
begin 
    FreeAndNil(FGatewayTypeAndFunctionList); 
end; 

initialization 
    TGatewayFactory.AddGateway(
    gtSwedbank, 
    function: TBaseGateway 
    begin 
     Result := TSwedbankGateway.Create; 
    end 
); 

end. 
+1

Yeni soru için teşekkürler. –

cevap

9

Bu bir derleyici kusurudur. Ünitenin başlangıç ​​bölümünde anonim bir yöntem tanımlamak, anonim yöntemin kesinleşmemesine ve sızdırıldığına yol açıyor gibi görünmektedir. Bu durumda, kodu başlatma bölümünden class constructor'a taşıyarak sorunu gidermek istiyorum. Yani

, böyle olmak tamamen initialization bölümü kaldırmak ve sınıf yapıcısı değiştirin: Bunu eklediğinizde

unit Unit1; 

interface 

implementation 

type 
    TProc = reference to procedure; 

var 
    Foo: TProc; 

initialization 
    ReportMemoryLeaksOnShutdown := True; 
    Foo := procedure begin end; 

end. 

:

İşte
class constructor TGatewayFactory.Create; 
begin 
    FGatewayTypeAndFunctionList := TList<TGatewayTypeAndFunction>.Create; 
    AddGateway(
    gtSwedbank, 
     function: TBaseGateway 
     begin 
     Result := TSwedbankGateway.Create; 
     end 
); 
end; 

Ben uydurmak en basit üreme olduğu Bir projede birim, anonim yöntem olarak sızdırıyor olarak rapor edilir.

Ama bu varyant bir sızıntı bildirmez:

unit Unit1; 

interface 

implementation 

type 
    TProc = reference to procedure; 

var 
    Foo: TProc; 

procedure DoInit; 
begin 
    Foo := procedure begin end; 
end; 

initialization 
    ReportMemoryLeaksOnShutdown := True; 
    DoInit; 

end. 

kusur XE8 giderilmiştir.