delphi - 如何解决界面乱七八糟的问题

标签 delphi interface delphi-2009

我一直认为接口(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/

相关文章:

c# - XML 序列化数据返回的最佳数据类型

delphi - GenoTechs GTSizer 组件

Java 自动完成不显示我在界面中创建的方法

delphi - Delphi 2009 和旧式对象类型的问题

c++ - 将数据从 Delphi DLL 传递到 C++ 应用程序

Delphi:实时运行时滚动

delphi - 在同一台计算机上安装 Rad Studio 2007 和 Rad Studio 2010

delphi - 是否有一个 Delphi 库可以返回项目的所有有效源路径?

c++ - Delphi 库内存管理器奇怪

java - 使用 Bottom Sheet 单中的接口(interface)