Prevention of destruction of the object transmitted through the interface

I do not have much experience with interfaces in Delphi and Delphi in general.

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 render objects that implement the IListModel interface.

 View = class(TForm) public constructor Create(model : IListModel); reintroduce; end; 

My application stores an instance of MyModel

 MyApp = class({...}) strict private model : MyModel; public // ... end; 

In the application, I create a 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 am wondering what is the best way to solve this problem. In MyApp, I could use both instance models: MyModel AND through the IListModel interface. Or I could introduce a new IMyModel interface and pass the model using this interface in the MyApp class. I had to use if Supports (...) in the ShowModel method to get the IListModel interface. Or I get the MyModel class from another base class non refcounting (TInterfacedPersistent or a self-written class). Any other ideas?

What is the best way to work with interfaces in such situations?

Edit: Base class non ref counting:

 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?

+4
source share
2 answers

If you want to use reference counting that comes with interfaces, you should only reference this object through interfaces. There are no object references except interfaces, and do not release the object yourself.

Or you can turn off reference counting by overriding _AddRef and _Release and destroy the object, as you are used to. This is what TComponent does.

Or keep reference counting, but call AddRef and Release when you reference it as an object.

change

using the const parameter prevents link counter updates and speeds up your code:

 constructor Create(const model : IListModel); reintroduce; 
+7
source

If you need both interfaces, interfaces, and object references, simply output the TInterfacedPersistent (declared in Classes.pas) instead of TInterfacedObject. Keep in mind that you must ensure that the interface reference is not saved when you release the instance.

+1
source

All Articles