avoid-unremovable-callbacks-in-listeners
Warns when an addListener
invocation receives a callback that cannot be unregistered.
Since no function expression (() => ...
or () { ... }
) is equal to any other function expression, passing it to addListener
creates a callback that cannot be unregistered via removeListener
and thus leads to a memory leak. Same applies to extension method tear-offs as they are never equal to each other (including methods with the same signature).
To fix that, assign the function expression to a field or variable and use that field or variable in both addListener
and removeListener
.
⚙️ Config
Set additional-methods
(default is empty) to include additional methods on top of addListener
and removeListener
(this option supports methods that accept a list of callbacks as well).
dcm:
rules:
- avoid-unremovable-callbacks-in-listeners:
additional-methods:
- addAll
- myCustomAddListener
Example
❌ Bad:
class SomeClass {
final _someListener = Listener();
void work() {
// LINT: Avoid passing function expressions as callbacks since they are never equal to each other and can't be unregistered.
_someListener.addListener(() {});
// LINT: Avoid passing function expressions as callbacks since they are never equal to each other and can't be unregistered
_someListener.addListener(() => null);
}
}
✅ Good:
class SomeClass {
final _someListener = Listener();
void work() {
_someListener.addListener(listener);
}
void listener() => print('empty');
}