Why do interface implementations based on TComponent leak memory?

前端 未结 3 1844
面向向阳花
面向向阳花 2021-02-04 04:09

This Delphi code will show a memory leak for an instance of TMyImplementation:

program LeakTest;

uses
  Classes;

type
  MyInterface = interface
  end;

  TMyIm         


        
相关标签:
3条回答
  • 2021-02-04 04:25

    A component is supposed to be owned and destroyed by something else, typically a form. In that scenario, reference count is not used. If you pass a component as an interface reference it would be very unfortunate if it was destroyed when the method returns.

    Therefore, reference counting in TComponent has been removed.

    0 讨论(0)
  • 2021-02-04 04:39

    Differences in implementation

    • TComponent._Release does not free your instance.
    • TInterfacedObject._Release does free your instance.

    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.

    Implementation of 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;
    
    0 讨论(0)
  • 2021-02-04 04:39

    TComponent doesn't implement its _AddRef and _Release methods the same as TInterfacedObject does. It defers its reference counting to its VCLComObject property, which should be some other interfaced object. Since TComponent doesn't count references, it can't detect when its reference count reaches zero, so it doesn't free itself.

    The VCLComObject property holds an interface reference, which should implement IVCLComObject. If a component's associated VCLComObject object has been told that it owns the component, then when that interface's reference count reaches zero, it will destroy its associated component. It's told it owns the component by calling its FreeOnRelease method.

    All this is designed to make it easier to wrap VCL components into COM objects. If that's not your goal, then you'll probably be fighting against several other unexpected design aspects along the way, so you might wish to re-evaluate your motivation for making your components implement interfaces in the first place.

    0 讨论(0)
提交回复
热议问题