我的代码在这里:
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不释放所有结构...
答案 0 :(得分:5)
您有循环参考。您对IInnerTest
的实施包含对ITest
的引用。您ITest
的实施会引用IInnerTest
。这个循环引用意味着接口引用计数永远不会为零。
这个问题的正常解决方案是使用弱引用。一些有用的链接: