I run in this situation where Destroy()
is never called.
unit Unit2;
interface
type
// Interface
ITest = Interface(IInterface)
function IsTrue() : Boolean;
end;
TmyClass = class(TInterfacedObject, ITest)
public
// Interface implementation
function IsTrue() : Boolean;
constructor Create();
destructor Destroy(); override;
end;
implementation
constructor TmyClass.Create();
begin
inherited Create();
end;
destructor TmyClass.Destroy();
begin
inherited Destroy();
end;
published
// Property
property IsItTrue: Boolean read IsTrue;
end.
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms,
Vcl.Dialogs, Vcl.StdCtrls, unit2;
type
TForm1 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
fMyClass: TmyClass;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
fMyClass.Free; // if refcount = 0 this works, if refcount <> 0 pointer error.
//or
fMyClass := Nil; // no error but Destroy wil not be executed
Close();
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
fMyClass := TMyClass.Create();
end;
end.
Reading this article, there is only a constructor but no destructor implemented.
Is there any particular reason for this?
And should I release (if needed) all other objects that will be defined in myClass
by implementing a finalization
section?
Your fMyClass
variable is an object reference, not an interface, so it does not participate in TInterfaceObject
's reference counting.
You need to change this:
fMyClass: TmyClass;
to this:
fMyClass: ITest;
And then you can get rid of fMyClass.Free;
altogether:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms,
Vcl.Dialogs, Vcl.StdCtrls, unit2;
type
TForm1 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
fMyClass: ITest;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
fMyClass := nil; // no error and Destroy will be executed
Close();
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
fMyClass := TMyClass.Create();
end;
end.
fMyClass := nil;
will invoke reference counting only if fMyClass
is an interface variable, not an object reference, and you can't call Free()
on an interface variable.