i don't have much experience with interfaces in Delphi and Delphi at all.
Example:
IListModel = interface
function At(row, col : Integer) : String;
end;
MyModel = class(TInterfacedObject, IListModel)
public
function At(row, col : Integer) : String;
procedure ManipulateA;
procedure ManipulateBogus;
end;
There is a view that can visualize objects that implement the IListModel interface.
View = class(TForm)
public
constructor Create(model : IListModel); reintroduce;
end;
My app holds a MyModel instance
MyApp = class({...})
strict private
model : MyModel;
public
// ...
end;
In the app i create the model and work with it.
procedure MyApp.LoadModel;
procedure MyApp.OnFoo;
begin
model.ManipulateBogus;
end;
Now, i want to show the data
procedure MyApp.ShowModel;
var
v : View;
begin
v := View.Create(model); // implicit to IListView > refCount=1
v.ShowModal;
FreeAndNil(v);
// refCount = 0
// oops, my model is dead now
end;
I'm wondering what's the best way to solve this problem. In MyApp i could hold both, the instance model : MyModel AND via IListModel interface. Or I could introduce a new interface IMyModel and hold the model by this interface in the MyApp class. I had to use if Supports(...) in the ShowModel method to get the IListModel interface. Or i derive the MyModel class from another non refcounting base class (TInterfacedPersistent or a self written class). Any other ideas?
What is the best way to work with interfaces in such situations?
Edit: A non ref counting base class:
function NonRefCountingObject.QueryInterface(const IID: TGUID;
out Obj): HResult;
begin
if GetInterface(IID, Obj) then
Result := S_OK
else
Result := E_NOINTERFACE;
end;
function NonRefCountingObject._AddRef: Integer;
begin
Result := -1; // no reference counting
end;
function NonRefCountingObject._Release: Integer;
begin
Result := -1; // no reference counting
end;
Is this implementation ok?
If you want to use the reference counting that comes with interfaces, you should only reference that object through interfaces. No references to the object other than through interfaces and do not free the object yourself.
Or you could disable the reference counting by overriding _AddRef and _Release and destroy the object like you are used to. This is what TComponent does.
Or keep the reference counting, but call AddRef and Release when you reference it like an object.
edit
using a const parameter prevents reference count updating and speeds up your code:
constructor Create(const model : IListModel); reintroduce;
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