delphi – 为什么基于TComponent的接口实现泄漏内存?

前端之家收集整理的这篇文章主要介绍了delphi – 为什么基于TComponent的接口实现泄漏内存?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
此Delphi代码显示TMyImplementation实例的内存泄漏:
program LeakTest;

uses
  Classes;

type
  MyInterface = interface
  end;

  TMyImplementation = class(TComponent,MyInterface)
  end;

  TMyContainer = class(TObject)
  private
    FInt: MyInterface;
  public
    property Impl: MyInterface read FInt write FInt;
  end;

var
  C: TMyContainer;
begin
  ReportMemoryLeaksOnShutdown := True;

  C := TMyContainer.Create;
  C.Impl := TMyImplementation.Create(nil);
  C.Free;
end.

如果TComponent被替换为TInterfacedObject,并且构造函数更改为Create(),则泄漏消失。这里有什么不同的TComponent?

非常感谢答案。总结一下:很容易,但是错误的说:“如果你使用的是接口,那么它们是引用计数的,因此它们被释放出来。”实际上,实现接口的任何类都可以打破这个规则。 (将不会显示编译器提示或警告。)

解决方法

实施差异

> TComponent._Release不释放你的实例。
> TInterfacedObject._Release确实释放你的实例。

也许有人可以铃声,但我认为,TComponent并不意味着我们通常使用接口的方式被用作引用计数对象。

TComponent._Release的实现

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

猜你在找的Delphi相关文章