释放内部接口问题的界面

时间:2013-01-03 12:19:16

标签: delphi delphi-7

我的代码在这里:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  IInnerTest = interface (IInterface)
    procedure DoSth;
  end;

  TRekScannerData = record
    Source: Integer;
    Device: IInnerTest;
  end;

  ITest = interface (IInterface)
    procedure DoSth;
  end;

  ATest = class(TInterfacedObject, ITest)
  private
    FInner: Array of TRekScannerData;
  public
    procedure DoSth;
    constructor Create();
    Destructor Destroy();override;
  end;

  AInnerTest = class (TInterfacedObject, IInnerTest)
  private
    FMainInt: ITest;
  public
    constructor Create(MainInt: ITest);
    procedure DoSth;
    Destructor Destroy();override;
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  test: ITest;

implementation

{$R *.dfm}

{ ATest }

constructor ATest.Create;
begin
  SetLength(FInner, 1);
  FInner[0].Device := AInnerTest.Create(self);
  //<----- Here is the reason. Passing main interface to the inner interface.
end;

destructor ATest.Destroy;
begin
  beep;
  inherited;
end;

procedure ATest.DoSth;
begin
  //
end;

{ AInnerTest }

constructor AInnerTest.Create(MainInt: ITest);
begin
  FMainInt := MainInt;
end;

destructor AInnerTest.Destroy;
begin
  beep;
  inherited;
end;

procedure AInnerTest.DoSth;
begin
  //
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  test := ATest.Create;
  test.DoSth;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  test := nil;
end;

end.

问题是当测试分配给nil时不会调用Destroy;

我想通过一个语句释放所有内部接口...... 可能吗?或者我是否需要在零之前使用其他方法销毁所有内部结构?

修改

班级结构如下:

Var x = ITest(ATest class) has ->
  Inner Interface: IInnerTest(AInnerTest class) which has reference to:
    ITest(ATest class)

Nil'ing x不释放所有结构...

1 个答案:

答案 0 :(得分:5)

您有循环参考。您对IInnerTest的实施包含对ITest的引用。您ITest的实施会引用IInnerTest。这个循环引用意味着接口引用计数永远不会为零。

这个问题的正常解决方案是使用弱引用。一些有用的链接: