If I implement an interface on a form such as TMyForm = class(TForm, IMyInterface)
, will the object free itself when there are no more interface references to it? It seems not to, although I couldn't work out how TForm is reference counted (if at all). I'm concerned about the form getting freed when an interface reference goes out of scope, but this does not seem to happen.
I guess there are two parts to the question, firstly whether a form might get unexpectedly freed (the real question), and secondly how forms are reference counted.
TForm
derives from TComponent
, which implements _AddRef()
and _Release()
to disable reference counting on itself. As such, any interface implemented by any TComponent
descendant class, like TForm
, will not free its implementing TComponent
object by default when the interface is released.
However, if an IVCLComObject
interface is assigned to the TComponent.VCLCOMObject
property, then TComponent
will delegate reference counting to that object, so that object can be freed if its reference count falls to 0 (TComponent
does not increment the reference count of its IVCLCOMObject
reference).
This is valid for all descendants of TComponent
, unless they implement any reference counting of their own by overriding _AddRef()
and _Release()
manually.
IF you implement an interface in a form, it can be worth adding your own
_Release as follows:
function _Release: Integer; stdcall;
function TMyInterfacedForm._Release: Integer;
begin
result:=-1;
end;
I found that it was possible to free a form with an interface, and then have the _Release called as the local variable went out of scope. This could produce an access violation, as the Tcomponent implementation checks to see if FVCLComObject is set
if FVCLComObject = nil then
Result := -1 // -1 indicates no reference counting is taking place
else
Result := IVCLComObject(FVCLComObject)._Release;
Since at this stage, FVCLComobject is undefined, an annoying A/V exception can occur.
By hardwiring the -1, it can be called safely without trigger exceptions.