接口循环引用导致的内存泄漏

接口如果之间循环引用,引用计数总是无法归零,会产生内存泄漏,下面是一个简单的实例,基于GC的Java,不会产生类似的泄漏.
unit Unit2;

interface

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

type
TForm2 = class(TForm)
btn1: TButton;
procedure btn1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

IChild=interface
['{ADA8F7F3-AA7D-4D57-8FA8-0FA501458981}']
procedure SetParent(AParent:IInterface);
procedure SetChild(AChild:IInterface);
end;

TChild=class(TInterfacedObject, IChild)
Parent:IInterface;
Child:IInterface;

procedure SetParent(AParent:IInterface);
procedure SetChild(AChild:IInterface);
end;

var
Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.btn1Click(Sender: TObject);
var
AChild:IChild;
AParent:IChild;
begin
AChild:=TChild.Create;
AParent:=TChild.Create;
AChild.SetParent(AParent);
AParent.SetChild(AChild);
end;

{ TChild }

procedure TChild.SetChild(AChild: IInterface);
begin
Child:=AChild;
end;

procedure TChild.SetParent(AParent: IInterface);
begin
Parent:=AParent;
end;

end.
如何绕过这种限制呢,就是使用基于指针的弱引用。下面是修改后的版本

unit Unit2;

interface

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

type
TForm2 = class(TForm)
btn1: TButton;
procedure btn1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

IChild=interface
['{ADA8F7F3-AA7D-4D57-8FA8-0FA501458981}']
procedure SetParent(AParent:IInterface);
procedure SetChild(AChild:IInterface);
procedure Show;
function GetParent:IChild;
end;

TChild=class(TInterfacedObject, IChild)
Parent:Pointer;
Child:IInterface;

procedure SetParent(AParent:IInterface);
procedure SetChild(AChild:IInterface);
procedure Show;
function GetParent:IChild;

end;

var
Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.btn1Click(Sender: TObject);
var
AChild:IChild;
AParent:IChild;
AButton:TButton;
begin
//AButton:=TButton.Create(nil);
AChild:=TChild.Create;
AParent:=TChild.Create;
AChild.SetParent(AParent);
AParent.SetChild(AChild);

AChild.GetParent.Show;
end;

{ TChild }

function TChild.GetParent: IChild;
begin
Result:=IChild(Parent);
end;

procedure TChild.SetChild(AChild: IInterface);
begin
Child:=AChild;
end;

procedure TChild.SetParent(AParent: IInterface);
begin
Parent:=Pointer(AParent);
end;

procedure TChild.Show;
begin
ShowMessage('ok');
end;

end.