I just noticed that
var
ObjList : TObjectList <TMyObject>;
...
ObjList := TObjectList <TMyObject>.Create (True);
ObjList.Add (TMyObject.Create);
ObjList.Clear;
does not free the object. Looking at the source code it seems that no cnRemoved
notification is triggered in Clear
(inherited from TList <T>
).
My question: Is this intentional? Is there any reason why one does not want to get these notifications in the case of Clear
? Or can this be considered as a bug in the collection classes?
EDIT
Turns out that a I put the line
inherited Create;
on the top of TMyObject
destructor, which was supposed to go into the constructor. This is why I got memory leaks reported that looked like the TObjectList
was not freeing the items. And a look at the source convinced me (I was trapped by the Count
property). Thanks for your help anyway!
The list frees owned objects when you call .Clear
. You've got a testing error. The code sample below, written on Delphi XE, displays this:
Calling CLEAR
Object deleted.
Object deleted.
After CLEAR. Press ENTER to free L and Exit.
The code in TList<T>.Clear
is deceiving, because Count
is actually a property. Look at SetCount()
, then look at DeleteRange()
and you'll see the code for Notify(oldItems[i], cnRemoved)
at the end of the DeleteRange
procedure.
program Project3;
{$APPTYPE CONSOLE}
uses SysUtils, Generics.Collections;
type
TDelObject = class
public
destructor Destroy;override;
end;
{ TDelObject }
destructor TDelObject.Destroy;
begin
WriteLn('Object deleted.');
inherited;
end;
var L:TObjectList<TDelObject>;
begin
L := TObjectList<TDelObject>.Create(True);
L.Add(TDelObject.Create);
L.Add(TDelObject.Create);
WriteLn('Calling CLEAR');
L.Clear;
WriteLn('After CLEAR. Press ENTER to free L and Exit.');
Readln;
L.Free;
end.
TList<T>.Clear
calls DeleteRange
to do the work. The last part of DeleteRange
runs around all the items calling Notify
passing cnRemoved
.
Your analysis of the code is thus incorrect. The cnRemoved
notification is duly delivered and owned objects are freed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With