我對Delphi和Delphi中的接口沒有太多經驗。防止通過接口傳遞對象的破壞
實施例:
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;
沒有可以可視化實現IListModel接口的對象的視圖。
View = class(TForm)
public
constructor Create(model : IListModel); reintroduce;
end;
我的應用程序擁有爲MyModel實例
MyApp = class({...})
strict private
model : MyModel;
public
// ...
end;
在應用程序中我創建了模型,並使用它。
procedure MyApp.LoadModel;
procedure MyApp.OnFoo;
begin
model.ManipulateBogus;
end;
現在,我想表明我不知道什麼是解決這個問題的最好辦法中的數據
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;
。 在MyApp中,我可以同時擁有實例模型:MyModel和通過IListModel接口。 或者我可以引入一個新的接口IMyModel,並通過MyApp類中的這個接口保存模型。我必須使用ShowModel方法中的Supports(...)來獲取IListModel接口。 或者我從另一個非refcounting基類(TInterfacedPersistent或自寫的類)派生MyModel類。任何其他想法?
在這種情況下使用接口的最佳方式是什麼?
編輯: 非裁判計數的基類:
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;
這是實現好不好?
Thx爲您的答案。用編輯中的NonRefCountingObject類替換TInterfacedObject或TComponent基類是否安全?這個實現是否正確? – hansmaad 2010-11-12 08:35:00
是的,正確的 – 2010-11-12 11:05:42
@hansmaad:Lars在他的第一句話中的含義是,你應該用'model:IListModel'替換'MyApp'中的'model:MyModel'。這確保'MyApp'保持一個引用(直到'MyApp'死亡;然後'model'的refcount減少,當refcount變爲零時,它被自動釋放)。 – 2010-11-12 12:07:45