In our application framework we have some kind of instance handler class that in resume it's responsible for capture the instances create by our others controllers/components/forms/etc.
Here's the declaration:
TInstanceHandler = class(TFrameworkClass)
strict private
FInstances : TList<TObject>;
procedure FreeInstances();
protected
procedure Initialize(); override;
procedure Finalize(); override;
public
function Delegate<T : class>(const AInstance : T) : T;
end;
And the implementation:
procedure TInstanceHandler.FreeInstances();
var AInstance : TObject;
begin
for AInstance in FInstances do
if(Assigned(AInstance)) then AInstance.Free();
FInstances.Free();
end;
procedure TInstanceHandler.Initialize();
begin
inherited;
FInstances := TList<TObject>.Create();
end;
procedure TInstanceHandler.Finalize();
begin
FreeInstances();
inherited;
end;
function TInstanceHandler.Delegate<T>(const AInstance : T) : T;
begin
FInstances.Add(AInstance);
end;
what happen sometimes is that our programmers forgot the existence of this class or his purpose and they free their instances.
Like this:
with InstanceHandler.Delegate(TStringList.Create()) do
try
//...
finally
Free();
end;
what happens next is that when TInstanceHandler
is finalized it will try to free the delegated instance again and this will lead to a error.
I know the season why Assigned
fail in this case and as far i can see i cant use FreeAndNil
.
so the question is: how i can correctly check if the reference was already freed?