From fdf61d11a8c999d6e9e35c4d30034194525d0889 Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Mon, 18 Sep 2023 11:55:17 -0700 Subject: [PATCH] Announce a breaking change of added `dispose()`. (#9397) --- src/release/breaking-changes/dispose.md | 63 +++++++++++++++++++++++++ src/release/breaking-changes/index.md | 2 + 2 files changed, 65 insertions(+) create mode 100644 src/release/breaking-changes/dispose.md diff --git a/src/release/breaking-changes/dispose.md b/src/release/breaking-changes/dispose.md new file mode 100644 index 00000000000..42236bd924c --- /dev/null +++ b/src/release/breaking-changes/dispose.md @@ -0,0 +1,63 @@ +--- +title: Added missing `dispose()` for some disposable objects in Flutter +description: > + 'dispose()' might fail because of double disposal. +--- + +## Summary + +Missing calls to 'dispose()' are added for some disposable objects. +For example, ContextMenuController did not dispose OverlayEntry, +and EditableTextState did not dispose TextSelectionOverlay. + +If some other code also invokes 'dispose()' for the object, +and the object is protected from double disposal, +the second 'dispose()' fails with the following error message: + +`Once you have called dispose() on a , it can no longer be used.` + +## Background + +The convention is that the owner of an object should dispose of it. + +This convention was broken in some places: +owners were not disposing the disposable objects. +The issue was fixed by adding a call to `dispose()`. +However, if the object is protected from double disposal, +this can cause failures when running in debug mode +and `dispose()` is called elsewhere on the object. + +## Migration guide + +If you encounter the following error, update your code to call `dispose()' only in cases when your code created the object. + +``` +Once you have called dispose() on a , it can no longer be used. +``` + +Code before migration: + +```dart +x.dispose(); +``` + +Code after migration: + +```dart +if (xIsCreatedByMe) { + x.dispose(); +} +``` + +To locate the incorrect disposal, check the call stack of the error. If the call stack points to `dispose` +in your code, this disposal is incorrect and should be fixed. + +If the error occurs in Flutter code, `dispose()` was +called incorrectly the first time. + +You can locate the incorrect call by temporary calling `print(StackTrace.current)` +in the body of the failed method `dispose`. + +## Timeline + +See the progress and status [in the tracking issue](https://github.com/flutter/flutter/issues/134787). diff --git a/src/release/breaking-changes/index.md b/src/release/breaking-changes/index.md index 8875da3c9c0..c8f6fb66086 100644 --- a/src/release/breaking-changes/index.md +++ b/src/release/breaking-changes/index.md @@ -51,6 +51,7 @@ release, and listed in alphabetical order: ### Released in Flutter 3.13 +* [Added missing `dispose()` for some disposable objects in Flutter][] * [Deprecated API removed after v3.10][] * [Added AppLifecycleState.hidden][] enum value * [Moved ReorderableListView's localized strings][] from material to widgets localizations @@ -60,6 +61,7 @@ release, and listed in alphabetical order: * [Migrate a Windows project to ensure the window is shown][] * [Updated `Checkbox.fillColor` behavior][] +[Added missing `dispose()` for some disposable objects in Flutter]: {{site.url}}/release/breaking-changes/dispose [Deprecated API removed after v3.10]: {{site.url}}/release/breaking-changes/3-10-deprecations [Added AppLifecycleState.hidden]: {{site.url}}/release/breaking-changes/add-applifecyclestate-hidden [Moved ReorderableListView's localized strings]: {{site.url}}/release/breaking-changes/material-localized-strings