Every now and then I see code, where a class descending from TComponent implements some interfaces, only interface references are used to the instances, and the expected behaviour is that the instances will free themselves when all the references went out of scope.
Bummer: TComponent by default is not reference counted.
It is when you assign VCLComObject an IVCLComObject which is hell to implement (Delphi provides two of them: TVCLAutoObject and TActiveFormControl. They sound heavey, and are).
Do not go that way. If you need some form of ownership in a class implementing an interface, then descend the class from TInterfacedObject, and add a field of TComponent that is the owner of things that need to be freed later on. In the destructor, free that field.
Something like this:
unit InterfacedObjectWithRootUnit;
interface
type
TInterfacedObjectWithRoot = class(TInterfacedObject)
strict private
FRoot: TComponent;
function GetRoot: TComponent;
strict protected
property Root: TComponent read GetRoot;
public
destructor Destroy; override;
end;
implementation
destructor TInterfacedObjectWithRoot.Destroy;
begin
if Assigned(FRoot) then
begin
FRoot.Free();
FRoot := nil;
end;
inherited Destroy();
end;
function TInterfacedObjectWithRoot.GetRoot: TComponent;
begin
if FRoot = nil then
FRoot := TComponent.Create(nil);
Result := FRoot;
end;
end.
–jeroen