代码之家  ›  专栏  ›  技术社区  ›  Roohome Com

正在使用删除地图。remove()导致未处理的异常:迭代期间的并发修改

  •  0
  • Roohome Com  · 技术社区  · 3 年前

    我正在尝试删除基于密钥的映射项。因此,我阅读了有关使用的文档。取下(钥匙)。然而,它返回错误。这是我的密码

    Future<bool> UpdateFilter() async{
        _selectedFilter['category'] = _category!=null ? _category : '';
        _selectedFilter['subCategory'] = _subCategory!=null ? _subCategory : '';
        _selectedFilter['type'] = _type;
        _selectedFilter['price'] = _price.end.round() > 0 ? [_price.start.round(),_price.end.round()] : [];
        _selectedFilter['bedroom'] = _bedroom.round();
        _selectedFilter['bathroom'] = _bathroom.round();
        _selectedFilter['lt'] = _landSize.end.round() > 0 ? [_landSize.start.round(),_landSize.end.round()] : [];
        _selectedFilter['lb'] = _buildingSize.end.round() > 0 ? [_buildingSize.start.round(),_buildingSize.end.round()] : [];
        //check for empty values then remove from filter
        _selectedFilter.forEach((key, value) {
          if(_selectedFilter[key].runtimeType == int && _selectedFilter[key]==0){
            _selectedFilter.remove(key); ===> does not work, consist errors
          }
          else if(_selectedFilter[key].isEmpty){
            _selectedFilter.remove(key); ===> does not work, consist errors
          }
        });
        _selectedFilter.remove('bedroom'); ===> it works without foreach (manually), for testing purpose
        _selectedFilter.remove('bathroom'); ===> it works without foreach (manually), for testing purpose
        return true;
      }
    

    下面是错误日志

    [VERBOSE-2:ui_dart_state.cc(209)]未处理的异常:并发 迭代期间的修改:_LinkedHashMapLen:7。 #0 _压缩迭代器。moveNext(dart:collection patch/compact_hash.dart:615:7) #1_LinkedHashMapMixin。forEach(dart:collection patch/compact_hash.dart:537:15) #2 _SearchState。UpdateFilter(包:rumahkita/pages/search.dart:65:21) #3 _SearchState。建筑(套餐:rumahkita/pages/search.省道:429:23) #4州。setState(包:flatter/src/widgets/framework.dart:1121:30) #5_搜索状态。建筑(套餐:rumahkita/pages/search.省道:428:21) #6 InkEstate_handleTap(包装:flift/src/material/ink_well.省道:989:21) #7手势识别器。invokeCallback(包:flatter/src/signities/recognizer.dart:198:24) #8点手势识别器。手拍(套装:颤振/src/signatures/tap.dart:608:11) #9 BaseTapgestureRecognitor_检查(套餐:颤振/src/signatures/tap.dart:296:5) #10 Bas<>

    有人知道为什么会这样吗?当我尝试手动删除时,它可以工作,但如果是内部循环功能,则会导致错误。

    2 回复  |  直到 3 年前
        1
  •  1
  •   jamesdlin    3 年前

    你在试着打电话 _selectedFilter.remove 从回调到 _selectedFilter.forEach .如 Map.forEach documentation :

    使命感 action 不得在地图上添加或删除关键点。

    一般来说 变异 您当前迭代的集合通常是自找麻烦(除非文档 明确地 说这是允许的),因为谁知道迭代将如何进行?如果你添加了一个项目,你会迭代添加的项目吗?如果您在已经迭代过的位置添加或删除了一个项目,该怎么办?如果删除了当前项目,下一个项目应该是什么?如果删除了当前项,然后又重新添加了它,是否应该再次迭代该项?等等

    处理这类事情的一般方法是保留要执行的操作的单独队列,然后在完成对集合的迭代后分别执行它们:

    var keysToRemove = <String>[];
    _selectedFilter.forEach((key, value) {
      if ((_selectedFilter[key] is int && _selectedFilter[key] == 0) ||
          _selectedFilter[key].isEmpty) {
        keysToRemove.add(key);
      }
    });
    for (var key in keysToRemove) {
      _selectedFilter.remove(key);
    }
    
        2
  •  1
  •   Valentin Vignal    3 年前

    你在绕圈子 _selectedFilter 的条目(带有 _selectedFilter.forEach(/* ... */) ). 当您在条目上循环时,不能同时删除/添加条目,因为不清楚应该发生什么。

    假设你正在循环列表 [0, 1, 2] (这与地图相同):

    final list = [0, 1, 2];
    for (final i in list) {
      if (i == 1) {
        list.push(3);
      }
    }
    

    现在还不清楚应该发生什么,应该发生什么 i 等于 3 在某个时刻,还是应该停止 2 ?


    如果只想删除一些与条件匹配的条目,可以使用

    _selectedFilter.removeWhere((key, value) {
      /* Your condition */
    });