Je n'ai pas beaucoup d'expérience avec les interfaces Delphi et Delphi du tout.Prévenir la destruction de l'objet passé par l'interface
Exemple:
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;
Il y a une vue qui peut visualiser des objets qui mettent en œuvre l'interface IListModel.
View = class(TForm)
public
constructor Create(model : IListModel); reintroduce;
end;
Mon application contient une instance MyModel
MyApp = class({...})
strict private
model : MyModel;
public
// ...
end;
Dans l'application je crée le modèle et travailler avec elle.
procedure MyApp.LoadModel;
procedure MyApp.OnFoo;
begin
model.ManipulateBogus;
end;
Maintenant, je veux montrer les données
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;
Je me demande quelle est la meilleure façon de résoudre ce problème. Dans MyApp, je pouvais contenir à la fois le modèle d'instance: MyModel ET via l'interface IListModel. Ou je pourrais introduire une nouvelle interface IMyModel et maintenir le modèle par cette interface dans la classe MyApp. J'ai dû utiliser si Supports (...) dans la méthode ShowModel pour obtenir l'interface IListModel. Ou je dérive la classe MyModel à partir d'une autre classe de base non refactoring (TInterfacedPersistent ou une classe auto-écrite). D'autres idées?
Quelle est la meilleure façon de travailler avec des interfaces dans de telles situations?
Edit: Une classe de base de comptage non ref:
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;
Est-ce ok la mise en œuvre?
Thx pour votre réponse. Est-il sûr de remplacer TInterfacedObject ou la classe de base TComponent avec la classe NonRefCountingObject de ma modification? Cette implémentation est-elle correcte? – hansmaad
Oui, c'est correct –
@hansmaad: Ce que Lars veut dire dans sa première phrase, c'est que vous devriez remplacer 'model: MyModel' dans' MyApp' par avec 'model: IListModel'.Cela fait en sorte que 'MyApp' conserve une référence (jusqu'à ce que' MyApp' meurt, alors le refcount de 'model' est diminué, quand ce refcount devient zéro, il est automatiquement libéré). –