如何正确释放 Firemonkey 控件,在本例中是带有父项的子窗体?

How to release a Firemonkey control properly, in this case a child form with a parent?

我想从控件本身的事件处理程序中删除并释放它。

TFmxObject.Release 的典型用例,不是吗?但是,它似乎只在 Windows 下有效,但在 Android 下无效,并且这种方法现在 已弃用 无论如何。

我知道,不起作用 不是一个很好的问题描述,但目前我无法在 android 下调试它。在 Windows 下,我看到事件处理程序在 .Release 之后正确继续,并且在它完成后,我的控件析构函数中的日志消息被执行。在 Android 下,应用程序挂起。

当我改用 .Free 时,它仍然在 Windows 下工作(析构函数立即发生,但处理程序在释放后不访问控件),并且在 Android 下没有明显的问题,但从未调用析构函数,所以我有泄漏。

使用 .DisposeOf 效果与使用 .Release 相同 - Windows ok,Android 挂起。

我也试过MyParent.RemoveComponent(MyControl),但都没有用。

我还需要做什么来释放所有引用以便 ARC 可以完成它的工作?或者怎么办?

TFmxObject.Release 在内部使用 TThread.ForceQueue,目前在 Android 下已被破坏(参见上面的讨论)。

作为解决方法,用于从其事件处理程序中释放对象的工作 cross-platform 版本将是

procedure TForm.CloseBtnClick(Sender: TObject);
begin
  Parent := nil;
  TThread.CreateAnonymousThread(
  procedure
  begin
    TThread.Queue(nil,
    procedure
    begin
      Self.DisposeOf;
    end);
  end).Start;
end;

请牢记重要的一点是,您不应保留对正在发布的控件的任何其他引用,否则您可能会遇到麻烦。

10.4 及更高版本的更新:

自 10.4 和统一内存管理以来,DisposeOf 现在在所有平台上等同于 Free,并且 Self.DisposeOf 可以替换为 Self.Free