-
Notifications
You must be signed in to change notification settings - Fork 9.8k
[Sensors] Fix:avoid calling setState() when mounted is false. #2361
Conversation
It is an error to call [setState] unless [mounted] is true.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @Notzuonotdied thank you for the PR, would you like to continue working on it? There are few comments which would be great if you can include them.
Please also follow the standard PR issue template (we have a check list etc).
Finally, please add an entry to the change log and increment the version (+1).
@@ -73,12 +73,14 @@ class SnakeState extends State<Snake> { | |||
void initState() { | |||
super.initState(); | |||
accelerometerEvents.listen((AccelerometerEvent event) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The return value of listen is a StreamSubscription<AccelerometerEvent>
. That should move into a _accelerometerEventSubscription
field. Please cancel()
it in the dispose
method.
@@ -73,12 +73,14 @@ class SnakeState extends State<Snake> { | |||
void initState() { | |||
super.initState(); | |||
accelerometerEvents.listen((AccelerometerEvent event) { | |||
if (!mounted) return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please add {
and }
to make things a bit cleared in the sample
setState(() { | ||
acceleration = event; | ||
}); | ||
}); | ||
|
||
Timer.periodic(const Duration(milliseconds: 200), (_) { | ||
if (!mounted) return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can actually replace the _
with timer
and then cancel
the timer as well, when not mounted.
Perhaps keep the timer in a _timer
field and cancel in the dispose
method as above. Sorry.
Closing due to lack of updates. |
It is an error to call [setState] unless [mounted] is true.
Description
The preferred solution is to cancel the timer or stop listening to the animation in the dispose() callback. Another solution is to check the "mounted" property of this object before calling setState() to ensure the object is still in the tree.
This error might indicate a memory leak if setState() is being called because another object is retaining a reference to this State object after it has been removed from the tree. To avoid memory leaks, consider breaking the reference to this object during dispose().
#0 State.setState. (package:flutter/src/widgets/framework.dart:1105:9)
#1 State.setState (package:flutter/src/widgets/framework.dart:1140:6)
#2 SnakeState.initState. (package:.../qy_sensors/snake.dart:77:7) // setState()
#3 _rootRunUnary (dart:async/zone.dart:1132:38)
#4 _CustomZone.runUnary (dart:async/zone.dart:1029:19)
#5 _CustomZone.runUnaryGuarded (dart:async/zone.dart:931:7)
#6 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:336:11)
#7 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:263:7)
#8 _ForwardingStreamSubscription._add (dart:async/stream_pipe.dart:132:11)
#9 _MapStream._handleData (dart:async/stream_pipe.dart:232:10)
#10 _ForwardingStreamSubscription._handleData (dart:async/stream_pipe.dart:164:13)
#11 _rootRunUnary (dart:async/zone.dart:1132:38)
#12 _CustomZone.runUnary (dart:async/zone.dart:1029:19)
#13 _CustomZone.runUnaryGuarded (dart:async/zone.dart:931:7)
#14 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:336:11)
#15 _DelayedData.perform (dart:async/stream_impl.dart:591:14)
#16 _StreamImplEvents.handleNext (dart:async/stream_impl.dart:707:11)
#17 _PendingEvents.schedule. (dart:async/stream_impl.dart:667:7)
#18 _rootRun (dart:async/zone.dart:1120:38)
#19 _CustomZone.run (dart:async/zone.dart:1021:19)
#20 _CustomZone.runGuarded (dart:async/zone.dart:923:7)
#21 _CustomZone.bindCallbackGuarded. (dart:async/zone.dart:963:23)
#22 _rootRun (dart:async/zone.dart:1124:13)
#23 _CustomZone.run (dart:async/zone.dart:1021:19)
#24 _CustomZone.runGuarded (dart:async/zone.dart:923:7)
#25 _CustomZone.bindCallbackGuarded. (dart:async/zone.dart:963:23)
#26 _microtaskLoop (dart:async/schedule_microtask.dart:41:21)
#27 _startMicrotaskLoop (dart:async/schedule_microtask.dart:50:5)