Skip to content

Commit

Permalink
Disallow dispose during listener callback (#114530)
Browse files Browse the repository at this point in the history
* Disallow dispose during listener callback

* addressing comment

* add comments to code

* Addressing comments

* fix test
  • Loading branch information
chunhtai authored Nov 18, 2022
1 parent 7fd3bb2 commit 3a3a0db
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 0 deletions.
6 changes: 6 additions & 0 deletions packages/flutter/lib/src/foundation/change_notifier.dart
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,12 @@ class ChangeNotifier implements Listenable {
@mustCallSuper
void dispose() {
assert(ChangeNotifier.debugAssertNotDisposed(this));
assert(
_notificationCallStackDepth == 0,
'The "dispose()" method on $this was called during the call to '
'"notifyListeners()". This is likely to cause errors since it modifies '
'the list of listeners while the list is being used.',
);
assert(() {
_debugDisposed = true;
return true;
Expand Down
16 changes: 16 additions & 0 deletions packages/flutter/test/foundation/change_notifier_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,22 @@ class Counter with ChangeNotifier {
}

void main() {
testWidgets('ChangeNotifier can not dispose in callback', (WidgetTester tester) async {
final TestNotifier test = TestNotifier();
bool callbackDidFinish = false;
void foo() {
test.dispose();
callbackDidFinish = true;
}

test.addListener(foo);
test.notify();
final AssertionError error = tester.takeException() as AssertionError;
expect(error.toString().contains('dispose()'), isTrue);
// Make sure it crashes during dispose call.
expect(callbackDidFinish, isFalse);
});

testWidgets('ChangeNotifier', (WidgetTester tester) async {
final List<String> log = <String>[];
void listener() {
Expand Down

0 comments on commit 3a3a0db

Please sign in to comment.