加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 工厂模式,内存泄漏

发布时间:2020-12-15 04:03:28 所属栏目:大数据 来源:网络整理
导读:我正在阅读Hodges的书“Delphi中的更多编码”,关于工厂模式的部分. 试着学习东西.把我的代码分解成小单元. 我使用ReportMemoryLeaksOnShutDown:= True;并且停止代码会导致内存泄漏.为什么会发生,我该如何解决? unit Unit2;interfaceuses Generics.Collecti
我正在阅读Hodges的书“Delphi中的更多编码”,关于工厂模式的部分.
试着学习东西.把我的代码分解成小单元.
我使用ReportMemoryLeaksOnShutDown:= True;并且停止代码会导致内存泄漏.为什么会发生,我该如何解决?
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.

解决方法

这是一个编译器缺陷.在单元的初始化部分中定义匿名方法似乎导致匿名方法未完成,因此泄露.在这种情况下,我将通过将代码从初始化部分移动到类构造函数来解决此问题.

因此,完全删除初始化部分,并将类构造函数更改为:

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

这是我可以编写的最简单的复制品:

unit Unit1;

interface

implementation

type
  TProc = reference to procedure;

var
  Foo: TProc;

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

end.

将此单元包含在项目中时,将报告匿名方法泄露.

但是这个变种没有报告泄漏:

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.

该缺陷在XE8中得到修复.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读