我一直认为接口(interface)是一种为不同的不相关类提供通用功能的方法。但是接口(interface)的属性 - “当 RefCOunt 降至零时释放对象”不允许我按照我想要的方式工作。
例如:假设我有两个不同的类:TMyObject 和 TMyDifferentObject。他们都支持这个接口(interface):
const
IID_MyInterface: TGUID = '{4D91C27F-510D-4673-8773-5D0569DFD168}';
type
IMyInterface = Interface(IInterface)
['{4D91C27F-510D-4673-8773-5D0569DFD168}']
function GetID : Integer;
end;
type
TMyObject = class(TInterfacedObject, IMyInterface)
function GetID: Integer;
end;
function TMyObject.GetID: Integer;
begin
Result := 1;
end;
type
TMyDifferentObject = class(TInterfacedObject, IMyInterface)
function GetID: Integer;
end;
function TMyDifferentObject.GetID: Integer;
begin
Result := 2;
end;
现在,我想在我的程序中创建此类的实例,然后将这些实例传递给此方法:
procedure ShowObjectID(AObject: TObject);
var
MyInterface: IMyInterface;
begin
if Supports(AObject, IID_MyInterface, MyInterface) then
begin
ShowMessage(IntToStr(MyInterface.GetID));
end;
end; //Interface goes out of scope and AObject is freed but I still want to work with that object!
这是一个例子。一般来说,我想将对象的实例传递给某个过程并检查该对象是否支持接口(interface),如果是,我想执行该接口(interface)的方法。但当接口(interface)超出范围时,我不想完成该对象的工作。如何做到这一点?
问候。
最佳答案
您的问题可能源于您使用对象引用创建对象的事实:
var
MyObject: TObject;
begin
MyObject := TMyObject.Create;
ShowMessage('Before ShowObjectID MyObject RefCount: ' + IntToStr(MyObject.RefCount));
ShowObjectID(MyObject);
ShowMessage('After ShowObjectID MyObject RefCount: ' + IntToStr(MyObject.RefCount));
end;
这样做意味着创建后的 RefCount 为零。只要您需要,就可以将您的对象分配给接口(interface)引用,
var
MyObject: TMyObject;
MyIntf: IMyInterface;
begin
MyObject := TMyObject.Create;
MyIntf := MyObject;
ShowMessage('Before ShowObjectID MyObject RefCount: ' + IntToStr(MyObject.RefCount));
ShowObjectID(MyObject);
ShowMessage('After ShowObjectID MyObject RefCount: ' + IntToStr(MyObject.RefCount));
MyIntf := nil;
ShowMessage('After nilling the interface MyObject RefCount: ' + IntToStr(MyObject.RefCount));
end;
或按照 David 在评论中建议的那样禁用重新计数。这本质上意味着声明您自己的“TInterfacedObject”并实现三个 IInterface 方法:
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
本质是_AddRef和_Release都返回-1
。正如 David 所说:看看 TComponent 是如何做到的。当 FVCLComObject 为零时,就看它正在做什么。
关于delphi - 如何解决界面乱七八糟的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7926022/