You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter:为何需要对ViewModel执行dispose操作?

Flutter ViewModel 销毁的直观案例与后果分析

案例1:未执行 dispose 的情况

假设我们有一个带定时器的 ViewModel,用来模拟持续占用资源的场景:

class TimerViewModel {
  late Timer _timer;
  int _count = 0;

  void startTimer() {
    _timer = Timer.periodic(const Duration(seconds: 1), (timer) {
      _count++;
      print("定时器运行中,计数:$_count");
    });
  }
}

// 对应页面
class TimerPage extends StatefulWidget {
  const TimerPage({super.key});

  @override
  State<TimerPage> createState() => _TimerPageState();
}

class _TimerPageState extends State<TimerPage> {
  final _viewModel = TimerViewModel();

  @override
  void initState() {
    super.initState();
    _viewModel.startTimer();
  }

  // 注意:这里没有调用ViewModel的dispose
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("定时器页面")),
      body: const Center(child: Text("返回后看控制台日志")),
    );
  }
}

现象:打开页面后定时器开始打印日志,但返回上一页后,控制台依然会持续输出计数日志——这说明TimerViewModel和它持有的定时器根本没被销毁,还在后台占用内存和CPU资源。

案例2:执行 dispose 的正确做法

给ViewModel添加销毁逻辑,页面销毁时调用:

class TimerViewModel {
  late Timer _timer;
  int _count = 0;

  void startTimer() {
    _timer = Timer.periodic(const Duration(seconds: 1), (timer) {
      _count++;
      print("定时器运行中,计数:$_count");
    });
  }

  // 添加dispose方法,释放资源
  void dispose() {
    _timer.cancel();
    print("定时器已取消,ViewModel资源释放");
  }
}

// 页面中调用dispose
class _TimerPageState extends State<TimerPage> {
  final _viewModel = TimerViewModel();

  @override
  void initState() {
    super.initState();
    _viewModel.startTimer();
  }

  @override
  void dispose() {
    _viewModel.dispose(); // 页面销毁时销毁ViewModel
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("定时器页面")),
      body: const Center(child: Text("返回后看控制台日志")),
    );
  }
}

现象:返回上一页后,控制台会打印“定时器已取消,ViewModel资源释放”,之后不再有计数日志——资源被正常回收,不会占用系统资源。

不执行 dispose 的真实后果

  1. 内存泄漏累积:如果应用频繁打开关闭这类页面,每次都会留下未销毁的ViewModel和资源,内存会持续上涨,最终导致应用卡顿、响应变慢。
  2. 意外行为/崩溃:如果ViewModel持有页面的BuildContext或订阅了网络请求,页面销毁后请求返回,ViewModel尝试更新已不存在的页面状态,会直接触发崩溃。
  3. 系统资源浪费:后台运行的定时器、未关闭的流监听会持续消耗CPU和电量,用户可能会因为耗电快卸载应用。

你现在觉得应用正常,是因为泄漏的资源还没达到临界值。但随着功能增多、用户使用时间变长,这些隐藏的问题会逐渐暴露出来。

内容的提问来源于stack exchange,提问作者Mark Dionnie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 22:50:26