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

向列表添加项时触发ConcurrentModificationError问题求助

Flutter ConcurrentModificationError 问题解决思路

在Flutter开发中,点击按钮向收藏列表添加一个或多个漫画时,偶发ConcurrentModificationError错误,报错信息为:Concurrent modification during iteration: Instance(length:7) of '_GrowableList'.,报错位置指向第17行,疑似来自getFavMangas()中的第二个for循环,已尝试5天仍未解决。

问题原因

这个错误核心是遍历列表的同时修改了该列表。你的favMangasListTitle是全局可变列表,当getFavMangas()在遍历它的过程中,如果其他异步操作(比如updateFavMangaList或页面跳转后的状态刷新)同时修改了这个列表,就会触发并发冲突。加上全局列表没有线程安全保护,Flutter的UI线程和异步任务容易同时访问列表导致报错。

解决方案

1. 改用局部变量替代全局列表

把favMangasListTitle和detailledMangaList改成getFavMangas()内部的局部变量,彻底避免外部操作意外修改遍历中的列表:

FirebaseFirestore firestore = FirebaseFirestore.instance;
String title = '1';
String read_chapter = '1';

Future<List> getFavMangas() async {
  var value = await firestore.collection("users/${user.uid}/fav_mangas").get();
  final favMangasGetter = value.docs.map((doc) => doc.data()).toList();
  
  // 改为方法内局部变量
  List favMangasListTitle = [];
  List detailledMangaList = [];

  for (var i in favMangasGetter) {
    title = i['title'];
    read_chapter = i['read_chapter'];
    favMangasListTitle.add(title);
  }

  for (var i in favMangasListTitle) {
    final mangas = await FirebaseFirestore.instance
        .collection('mangas')
        .where('title', isEqualTo: i)
        .get();

    final receivedMangaDetailled =
        mangas.docs.map((doc) => doc.data()).toList();
    detailledMangaList.addAll(receivedMangaDetailled);
  }
  print(detailledMangaList);
  return detailledMangaList;
}

2. 确保异步操作顺序执行

按钮点击时,updateFavMangaList()是异步函数,你之前没有等待它完成就执行setState和页面跳转,可能导致getFavMangas()在更新未完成时就读取列表,引发冲突。修改按钮事件,等待更新完成后再执行后续操作:

Directionality(
  textDirection: TextDirection.rtl,
  child: ElevatedButton.icon(
    onPressed: () async {
      // 等待收藏列表更新完成
      await updateFavMangaList();
      setState(() {});
      // 等待页面返回后再刷新状态
      await Navigator.push(
        context,
        MaterialPageRoute(builder: (context) => MangathequePage())
      );
      setState(() {});
    },
    icon: Icon(Icons.arrow_back),
    label: Text('Suivant'),
  ),
),

3. 遍历列表时使用副本(保留全局列表的备选方案)

如果必须保留全局的favMangasListTitle,遍历前创建一个列表副本,避免遍历原列表时被外部修改:

// 第二个for循环改为遍历列表副本
for (var i in List.from(favMangasListTitle)) {
  final mangas = await FirebaseFirestore.instance
      .collection('mangas')
      .where('title', isEqualTo: i)
      .get();

  final receivedMangaDetailled =
      mangas.docs.map((doc) => doc.data()).toList();
  detailledMangaList.addAll(receivedMangaDetailled);
}

额外优化建议

  • 减少全局可变状态的使用,改用StatefulWidget的本地状态或专门的状态管理库(如Provider、Riverpod)管理收藏列表,从根源避免全局变量带来的并发问题。
  • updateFavMangaList()开头的get()调用没有实际作用,可以直接删除,简化代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 15:51:55