I am looking at the flutter example below;
https://docs.flutter.dev/cookbook/forms/text-field-changes#interactive-example
it has code like;
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Retrieve Text Input',
home: MyCustomForm(),
);
}
}
// Define a custom Form widget.
class MyCustomForm extends StatefulWidget {
const MyCustomForm({super.key});
@override
State<MyCustomForm> createState() => _MyCustomFormState();
}
// Define a corresponding State class.
// This class holds data related to the Form.
class _MyCustomFormState extends State<MyCustomForm> {
// Create a text controller and use it to retrieve the current value
// of the TextField.
final myController = TextEditingController();
@override
void initState() {
super.initState();
// Start listening to changes.
myController.addListener(_printLatestValue);
}
@override
void dispose() {
// Clean up the controller when the widget is removed from the widget tree.
// This also removes the _printLatestValue listener.
myController.dispose();
super.dispose();
}
void _printLatestValue() {
print('Second text field: ${myController.text}');
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Retrieve Text Input'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
TextField(
onChanged: (text) {
print('First text field: $text');
},
),
TextField(
controller: myController,
),
],
),
),
);
}
}
and following method within;
@override
void dispose() {
// Clean up the controller when the widget is removed from the widget tree.
// This also removes the _printLatestValue listener.
myController.dispose();
super.dispose();
}
What I see here myController
is already instance of _MyCustomFormState
class. So my assumption is once MyCustomForm
widget removed from widget tree, all it's instance members should be automatically disposed right? But it is recommended to call dispose
method of those members explicitly.
Can I learn why framework does not do it itself and we need to handle it? I would understand if that holds a handle to a file system which is outside of that class scope, but what I see in there there is no handle of this controller outside of the scope.
When an instance is no longer used, (like your _MyCustomFormState
), it is automatically garbage-collected, together with all the references it contains, like your myController
.
However, a TextEditingController
instance may have more resources attached to it than can be reclaimed by simple garbage collection.
Therefore is is recommended to call its dispose
method before the memory is reclaimed.
Unlike for instance C++, Dart does not have a concept of destructors for its classes, so the call to dispose
methods is needed.