颤振错误:在 dispose() 之后调用 setState()

Чак*_*онс 6 dart flutter

我编写了代码每 60 秒获取一次数据并显示在屏幕上。当应用程序启动时,它会在调试控制台中显示错误。代码工作正常,每 60 秒获取一次数据并显示在屏幕上。

错误:

E/flutter(2021):#6 _CustomZone.bindUnaryCallbackGuarded。(dart:async/zone.dart:1207:26) E/flutter (2021): #7 _rootRunUnary (dart:async/zone.dart:1370:13) E/flutter (2021): #8 _CustomZone.runUnary (dart :async/zone.dart:1265:19) E/flutter (2021): #9 _CustomZone.bindUnaryCallback。(dart:async/zone.dart:1191:26) E/flutter (2021): #10 _Timer._runTimers (dart:isolate-patch/timer_impl.dart:395:19) E/flutter (2021): #11 _Timer ._handleMessage (dart:isolate-patch/timer_impl.dart:426:5) E/flutter ( 2021): #12 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12) E/flutter ( 2021) :E / flutter(2021):[错误:flutter / lib / ui / ui_dart_state.cc(199)]未处理的异常:在dispose()之后调用setState():_EvrokoVipScreenState#98462(生命周期状态:已失效,未安装)E / flutter (2021):如果您对不再出现在小部件树中的小部件的 State 对象调用 setState()(例如,其父小部件不再在其构建中包含该小部件),则会发生此错误。当代码从计时器或动画回调调用 setState() 时,可能会发生此错误。E/flutter (2021):首选的解决方案是在 dispose() 回调中取消定时器或停止监听动画。另一个解决方案是在调用 setState() 之前检查该对象的“mounted”属性,以确保该对象仍在树中。E/flutter (2021):如果调用 setState(),此错误可能表示内存泄漏,因为另一个对象在从树中删除后仍保留对此 State 对象的引用。为了避免内存泄漏,请考虑在 dispose() 期间中断对此对象的引用。

  void initState() {
    // TODO: implement initState
    super.initState();
    if (mounted) {
      fetchDataVip();
      new Timer.periodic(Duration(seconds: 60), (Timer t) => setState(() {}));
    }
  }
Run Code Online (Sandbox Code Playgroud)

小智 10

我认为你应该在使用计时器后将其丢弃。应该是这样的。

late var timer;
void initState() {
// TODO: implement initState
super.initState();
if (mounted) {
  fetchDataVip();
  timer = new Timer.periodic(Duration(seconds: 60), (Timer t) => setState(() {}));
}
}
  
@override
void dispose() {
  timer.cancel();
  super.dispose();
}
Run Code Online (Sandbox Code Playgroud)


Val*_*nal 5

当您的小部件被处置时,您需要取消计时器:

void initState() {
  super.initState();
  fetchDataVip();
  new Timer.periodic(Duration(seconds: 60), (Timer t) {
    if (!mounted) {
      timer.cancel();
    } else {
      setState(() {});
    }
  });
}
Run Code Online (Sandbox Code Playgroud)

而且您不需要检查您的小部件是否安装在initState.