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

使用Provider触发A InspectionFormProvider已释放后使用错误的原因排查

错误成因分析:A InspectionFormProvider was used after being disposed.

核心成因

  • 直接复用外部Provider实例,生命周期失控
    你在ChangeNotifierProvider的create方法里返回了一个外部的inspectionFormProvider实例,而非在create内部创建新实例。当Provider关联的Widget被销毁时,框架会自动调用该实例的dispose()方法释放资源。但按钮的onPressed回调直接持有这个外部实例的引用,一旦实例被销毁,点击按钮调用insertItem()就会触发"已销毁实例被使用"的错误。

  • 未通过Widget树上下文获取存活的Provider实例
    按钮逻辑里没有通过context获取当前Widget树中存活的Provider实例,而是直接使用外部引用。这种方式完全脱离了Provider框架的生命周期管理,无法感知实例是否已被销毁。

  • Provider生命周期与使用范围不匹配
    当前ChangeNotifierProvider的子Widget是Row,一旦Row被移除出Widget树,对应的Provider实例就会被销毁。但按钮回调仍然持有该实例的引用,后续点击必然访问已释放的对象。


修复方案

  1. 在create内部创建新实例
    让Provider框架管理实例的生命周期,避免外部复用:

    ChangeNotifierProvider(
      create: (_) => InspectionFormProvider(), // 内部生成新实例
      child: Row(
        mainAxisSize: MainAxisSize.max,
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          // ... 其余代码
        ],
      ),
    )
    
  2. 通过context获取存活的Provider实例
    修改按钮的onPressed逻辑,通过上下文获取当前有效的Provider:

    ElevatedButton.icon(
      icon: Icon(...),
      label: Text(...),
      onPressed: () {
        // 用listen: false避免不必要的监听
        Provider.of<InspectionFormProvider>(context, listen: false).insertItem();
      },
    )
    
  3. 调整Provider层级(按需)
    如果InspectionFormProvider需要跨多个Widget共享,或者生命周期长于当前Row,可以将ChangeNotifierProvider提升到更高层级(比如页面根Widget、MaterialApp),防止实例被过早销毁。

内容的提问来源于stack exchange,提问作者Unknown Developer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 03:55:25