在依赖对象

时间:2017-11-17 09:45:41

标签: delphi memory-leaks interface reference-counting tinterfacedobject

简介

我发现我的代码泄漏了TInterfacedObject实例的内存,我将其作为接口引用保留。虽然我在使用后将参考变量重置为nil,但它仍然存活。

泄漏的对象属于TMasterObject类,它实现了两个接口IInterfaceXIInterfaceY。对象的引用保存在IInterfaceY类型的变量中。

TMasterObject IInterfaceX的实施仅仅是巧合。因为它有两个TSomeObject实例,需要引用此接口,所以我也在TMasterObject中实现了它。

MCVE / SSCCE

program InterfaceDependencies;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

type
  IInterfaceX = interface end;

  IInterfaceY = interface end;

  TSomeObject = class(TObject)
    FReference: IInterfaceX;
    constructor Create(AReferenceX: IInterfaceX);
  end;

  TMasterObject = class(TInterfacedObject, IInterfaceX, IInterfaceY)
    FObjectA: TSomeObject;
    FObjectB: TSomeObject;
    constructor Create;
    destructor Destroy; override;
  end;

{ TSomeObject }

constructor TSomeObject.Create(AReferenceX: IInterfaceX);
begin
  FReference := AReferenceX;
end;

{ TMasterObject }

constructor TMasterObject.Create;
begin
  FObjectA := TSomeObject.Create(Self); // increments "FRefCount" by 1
  FObjectB := TSomeObject.Create(Self); // increments "FRefCount" by 1
end;

destructor TMasterObject.Destroy;
begin
  FObjectA.Free;
  FObjectB.Free;

  inherited;
end;

var
  LMasterObject: IInterfaceY;
begin
  try
    LMasterObject := TMasterObject.Create;
    // 'TMasterObject(LMasterObject).FRefCount' is now "3" because of 'FObjectA.FReference' and 'FObjectB.FReference'
    LMasterObject := nil; // decrements 'TMasterObject(LMasterObject).FRefCount' by 1
    // 'LMasterObject' is not destroyed because 'TMasterObject(LMasterObject).FRefCount' is still "2"
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

问题

可以使用哪些策略

  1. 解决此特定问题和
  2. 将来避免这样的问题?

0 个答案:

没有答案
相关问题