To provide as much information as I can, here’s a very basic example of what I’m doing
type
IMyInterface = interface
[THE_GUID_HERE]
// some methods
end;
TMyInterfaceArray = Array of IMyInterface;
TMyInterfacedObject = class(TInterfacedObject, IMyInterface)
// implementation of the Interface etc. here
end;
TContainingObject = class
private
FIObjectArray: TMyInterfaceArray;
public
constructor Create;
destructor Destroy; override;
procedure NewInstanceOfInterfacedObject;
end;
implementation
constructor TContainingObject.Create;
begin
inherited;
// Just to illustrate that an Instance is being created...
NewInstanceOfInterfacedObject;
end;
destructor TContainingObject.Destroy;
var
I: Integer;
begin
for I := Low(FIObjectArray) to High(FIObjectArray) do
FIObjectArray[I] := nil;
SetLength(FIObjectArray, 0); // Array collapsed
inherited;
end;
procedure TContainingObject.NewInstanceOfInterfacedObject;
var
LIndex: Integer;
begin
LIndex := Length(FIObjectArray);
SetLength(FIObjectArray, LIndex + 1);
FIObjectArray[LIndex] := TMyInterfacedObject.Create;
end;
Okay, so an instance of TContainingObject is created, and in turn creates an instance of TMyInterfacedObject, stored in an Array of IMyInterface.
When TContainingObject‘s destructor is called, it nil’s the reference and collapses the Array.
The issue I have is that, with no other references anywhere, TMyInterfacedObject‘s destructor is never called, and thus memory leaks.
Am I doing something wrong, or is Delphi’s reference counting system not able to cope with the simple concept of Interfaced Objects being held in an Array of the Interface Type?
Thanks for any advice!
MORE INFORMATION
TContainingObject provides an Array property to access individual instances of IMyInterface contained within the Array.
In my actual code, there are circular references between multiple Interface types.
Let’s suggest that IMyInterface contains a function GetSomething: IAnotherInterface, and IAnotherInterface contains GetMyInterface: IMyInterface (a circular reference).
Could this be causing my problem? If so, the circular reference is absolutely required, so what would a solution be with that in mind?
If the implementation for
IMyInterfacecontains anIAnotherInterfacemember, and the implementation forIAnotherInterfacecontains anIMyInterfacemember, and they refer to each other, then their reference counts will never be able to fall to 0 unless you clear one of the references, which likely means adding methods to your interfaces to do that, eg:.
Now watch the reference counts when you don’t explicitally free one of the references:
Now add an explicit release to one of the references:
.