-
Notifications
You must be signed in to change notification settings - Fork 1.3k
fix guard ScrollController with positions check #4029
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
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.
Code Review
This review identified a potential memory leak due to an undisposed _scrollController and a critical race condition in the scrollDown method. These findings highlight important areas for improving the stability and performance of the application.
| void scrollDown() async { | ||
| if (_scrollController.hasClients) { | ||
| await Future.delayed(const Duration(milliseconds: 250)); | ||
| _scrollController.animateTo( | ||
| _scrollController.position.maxScrollExtent, | ||
| duration: const Duration(milliseconds: 200), | ||
| curve: Curves.easeOut, | ||
| ); | ||
| } |
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.
There is a race condition here. The _scrollController.hasClients check is performed before an await. After the Future.delayed completes, the widget might have been disposed, and _scrollController might no longer have clients. Accessing _scrollController.position would then throw an exception. The checks for mounted and hasClients (or positions.isNotEmpty) should be performed after any await calls to ensure the state is still valid before using the controller.
| void dispose() { | ||
| _scrollController.dispose(); | ||
| _questionAnimationController.dispose(); | ||
| super.dispose(); | ||
| } |
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.
|
so _scrollController.hasClients does not work? |
hasClients only checks that the controller is attached at that moment. Since scrollDown waits before running, the list can detach in between so accessing position will crash |
omi/app/lib/pages/speech_profile/page.dart
Line 85 in ef7ad36
ScrollController had no attached position because the ListView was not built yet, that’s whyu position became invalid
closes #4023