跳至主要内容

为 Flutter 中的一些可释放对象添加了缺失的 `dispose()`

摘要

#

为一些可释放对象添加了缺失的 'dispose()' 调用。例如,ContextMenuController 没有释放 OverlayEntry,而 EditableTextState 没有释放 TextSelectionOverlay。

如果某些其他代码也为该对象调用了 'dispose()',并且该对象受到双重释放保护,则第二个 'dispose()' 将失败并显示以下错误消息

一旦您在 <类名> 上调用了 dispose(),就无法再使用它。

背景

#

约定是对象的拥有者应该释放它。

此约定在某些地方被破坏了:所有者没有释放可释放对象。该问题通过添加对 dispose() 的调用得到修复。但是,如果对象受到双重释放保护,这可能会导致在调试模式下运行时发生故障,并且在对象上的其他位置调用 dispose()

迁移指南

#

如果您遇到以下错误,请更新您的代码,仅在您的代码创建了对象的情况下调用 dispose()

Once you have called dispose() on a <class name>, it can no longer be used.

迁移前的代码

dart
x.dispose();

迁移后的代码

dart
if (xIsCreatedByMe) {
  x.dispose();
}

要查找不正确的释放,请检查错误的调用堆栈。如果调用堆栈指向您代码中的 dispose,则此释放不正确,应予以修复。

如果错误发生在 Flutter 代码中,则 dispose() 第一次被错误地调用。

您可以通过在失败的方法 dispose 的主体中临时调用 print(StackTrace.current) 来找到不正确的调用。

时间线

#

查看跟踪问题中的进度和状态