[教程]栈上接口对象在匿名函数中的使用时请注意内存泄露问题

首先看下面的示例代码:

type
  TTestInterface=class(TInterfacedObject)
  public
    destructor Destroy;override;
  end;
procedure TForm1.BitBtn1Click(Sender: TObject);
var
   ATest:IInterface;
begin
ATest:=TTestInterface.Create;
TThread.ForceQueue(nil,procedure
  begin
  ShowMessage(IntToStr(ATest._AddRef));
  ATest._Release;
  end);
end;

{ TTestInterface }

destructor TTestInterface.Destroy;
begin
  ShowMessage('Object Free');
  inherited;
end;

一般来说,我们认为 Delphi 自己管理接口的引用计数,所以不太会注意,但是,在上面的示例中,由于要保证 ATest 在匿名函数中的可用性,Delphi 并没有在函数退出时,减少 ATest 的引用计数,而在匿名函数执行完成后,同样也并没有减少计数,这就造成了 ATest 实例的引用计数没有减少到0,然后就出现了内存泄露的问题。这块已知在10.3.1中已经不存在该问题,感谢菜根提醒

至于当前的策略,在你的匿名函数调用退出前,将 ATest 的地址设置为 nil 就可以了。

滚动至顶部