问题描述
此Delphi代码将显示TMyImplementation实例的内存泄漏:
This Delphi code will show a memory leak for an instance of 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有什么不同?
If TComponent is replaced by TInterfacedObject and the constructor changed to Create(), the leak disappears. What is different with TComponent here?
非常感谢您的答案。总结一下:很容易,但是错误的说:如果你使用的是接口,那么它们是引用计数的,因此它们被释放出来。实际上,实现接口的任何类都可以打破这个规则。 (将不会显示任何编译器提示或警告。)
Many thanks for the answers. To sum up: it is easy, but wrong, to say "If you are using interfaces, they are reference counted and hence they are freed for you." - Actually any class which implements an interface can break this rule. (And there will be no compiler hint or warning be shown.)
推荐答案
实现差异
-
TComponent._Release
不释放您的实例。 -
TInterfacedObject._Release
免费您的实例。 TComponent._Release
does not free your instance.TInterfacedObject._Release
does free your instance.
Differences in implementation
也许有人可以铃声,但我认为这是 TComponent
不是用作引用计数对象方式我们通常使用接口。
Perhaps someone can chime in but my take on this is that TComponent
is not meant to be used as a reference counted object the way we normally use interfaces.
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;
这篇关于为什么基于TComponent的接口实现泄漏内存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!