【问题标题】:Will an interface-implementing form free itself when there are no more references to it?当没有更多引用时,接口实现表单会自行释放吗?
【发布时间】:2013-12-21 14:39:11
【问题描述】:

如果我在诸如TMyForm = class(TForm, IMyInterface) 这样的表单上实现一个接口,当没有更多的接口引用时,该对象是否会自行释放?似乎没有,尽管我无法弄清楚 TForm 是如何被引用计数的(如果有的话)。我担心当接口引用超出范围时表单会被释放,但这似乎没有发生。

我想这个问题有两个部分,首先是表单是否会被意外释放(真正的问题),其次是表单是如何被引用计数的。

【问题讨论】:

  • @TLama TForm 继承自 TComponent,它实现了 IInterface 和 IInterfaceComponentReference。 TComponent 确实实现了 _AddRef 和 _Release,但它们似乎只是有条件地进行引用计数。
  • @Alister: TComponent 禁用对自身的引用计数,但会对其VCLCOMObject 属性执行引用计数(如果已分配)。
  • @Alister,对不起,也许我误解了你的问题(在重读几次之前),但我想你是在问如果你添加一个接口会发生什么(将在@987654324 中实现@ 班级)。如果添加该接口在某种程度上是危险的,并且如果这会向表单添加引用计数。
  • @TLama:向TForm 添加接口不会向TForm 添加引用计数。编译器仍会在交互指针上调用_AddRef()_Release(),但由于TComponent,它们将是无操作的。
  • 没那么简单,@Free。看看其他人在这里写了什么。特别是,Remy 在您之前的评论,Uwe 的回答,以及问题中报告它没有那样工作的地方。

标签: delphi interface tform


【解决方案1】:

TForm 派生自 TComponent,它实现了 _AddRef()_Release() 以禁用自身的引用计数。因此,由任何TComponent 后代类实现的任何接口,如TForm,在释放接口时默认不会释放其实现的TComponent 对象。

但是,如果将IVCLComObject 接口分配给TComponent.VCLCOMObject 属性,则TComponent 会将引用计数委托给该对象,因此如果该对象的引用计数降至0(TComponent 不会不增加其IVCLCOMObject 引用的引用计数)。

这对TComponent 的所有后代都有效,除非它们通过手动覆盖_AddRef()_Release() 来实现自己的任何引用计数。

【讨论】:

  • 我更担心还有什么可能会设置 VCLComObject。
  • @Alister: TComponent.VCLCOMObject 在访问TComponent.ComObject 时被设置,这仅在项目使用VCLCom 单元时有效(否则访问ComObject 属性将引发异常) .
  • 换句话说:只要您不通过 COM 服务器以某种方式公开您的表单,在此引用计数似乎足够了,那么在没有您自己干预的情况下设置 VCLComObject 的可能性很小。跨度>
【解决方案2】:

如果您在表单中实现接口,则值得添加自己的接口

_Release as follows:

    function _Release: Integer; stdcall;

function TMyInterfacedForm._Release: Integer;
begin
  result:=-1; 
end;

我发现可以释放带有接口的表单,然后在局部变量超出范围时调用 _Release。这可能会产生访问冲突,因为 Tcomponent 实现会检查是否设置了 FVCLComObject

  if FVCLComObject = nil then
    Result := -1   // -1 indicates no reference counting is taking place
  else
    Result := IVCLComObject(FVCLComObject)._Release;

由于在这个阶段,FVCLComobject 是未定义的,因此可能会出现烦人的 A/V 异常。 通过硬连线 -1,可以安全地调用它而不会触发异常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-09
    • 1970-01-01
    相关资源
    最近更新 更多