Reading the Expert Delphi book I have found something that I cannot understand. The author has created an unit with this code:
IToDoData = interface //CRUD
function ToDoCreate(aValue: TToDo): integer;
function ToDoRead(id: integer; out aValue: TToDo): boolean;
function ToDoUpdate(aValue: TToDo): boolean;
function ToDoDelete(id: integer): boolean;
procedure ToDoList(aList: TToDos);
end;
Then he decided to use a DataModule
and implement the above interface in this way:
type
TDMToDo = class(TDataModule, IToDoData)
// ... other code ...
public
// IToDoData
function ToDoCreate(aValue: TToDo): integer;
function ToDoRead(id: integer; out aValue: TToDo): boolean;
function ToDoUpdate(aValue: TToDo): boolean;
function ToDoDelete(id: integer): boolean;
procedure ToDoList(aList: TToDos);
end;
So far so good but note that he didn't put TInterfacedObject
so here we haven't methods like AddRef and so on. My guess is that the above code is fine but it has to be included inside the try ... finally block.
In the main form (the data module unit is the uses clauses of course) there is a function like this:
function TFormToDo.GetToDoData: IToDoData;
begin
if DMToDo = nil then
DMToDo := TDMToDo.Create(Application);
Result := DMToDo;
end;
The code above allows to write code like this:
begin
GetToDoData.ToDoList(FToDos);
ListView1.BeginUpdate;
try
//populate the list
finally
ListView1.EndUpdate;
end;
end;
Doesn't this produce a memory leak? At least on windows. I am new to delphi so I might fail but I have read online that Android and IOs has ARC so no need to worry about try finally.
Windows does NOT have ARC so I have to use the try .. finally unless there is an implementation like TInterfacedObject (here there isn't). So is that a mistake?
The app is about a ToDo app in which you write/read/save your notes. The data module has FireDAC access components and the interface methods are used to access the db. This is to keep a separation between UI and db stuff.
TDataModule
is TComponent
descendant, and TComponent
implements IInterface
and related reference counting methods
TComponent = class(TPersistent, IInterface, IInterfaceComponentReference)
However, TComponent
has reference counting disabled and components are managed either manually or through ownership model on non-ARC compiler.
To be more precise, TComponent
has disabled reference counting unless it serves as wrapper for Windows COM object. Which is not the case here.
On ARC compiler there is slight complication with manual management - actually automatic management, because if you don't allow TComponent
descendants to be managed through ownership, they have to be released with DisposeOf
.
TComponent
behavior is different than TInterfacedObject
behavior regarding reference counting on classic compiler.
In above case, there is no leak because Application
owns that data module and it will manage data module lifetime appropriately on all compilers.
try... finally
block is there not for memory management, but to protect BeginUpdate... EndUpdate
You have to leave try...finally
on all compilers.
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