I have a code here:
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.
The problem is that Destroy is not called when test is assigned to nil;
I would like to release all the inner interfaces by one statement ... Is it possible? or do I need to prior to nil destroy all inner structures by using another method?
The class structure is as follows:
Var x = ITest(ATest class) has ->
Inner Interface: IInnerTest(AInnerTest class) which has reference to:
ITest(ATest class)
Nil'ing x doesn't release all structure ...
You have a circular reference. Your implementation of IInnerTest
holds a reference to ITest
. And your implementation of ITest
holds a reference to IInnerTest
. And this circular reference means that the interface reference count can never go to zero.
The normal solution to this issue to to use a weak reference. Some useful links:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With