dart 异常:迭代期间并发修改:'_GrowableList'的示例(长度:17)

cetgtptt  于 2023-11-14  发布在  其他
关注(0)|答案(6)|浏览(121)

我做了一个游戏,在//ERROR ZONE中被称为异常,我不明白。类游戏有List重排序。

void spawnt(){
var rnd = new Random();
var rnd2 = new Random();
rnd = rnd.nextInt(100);
if(rnd2.nextBool())
  rnd2 = rnd2.nextInt(100);
else
  rnd2 = -rnd2.nextInt(100);
var x = flappy.position["x"]+lastx+sw+rnd;
var y = rnd2*pomer-100-1800*pomer-168*pomer;
Rectangle vrch = new Rectangle("img/tube1.png", sw, sh, {"x":x, "y":y, "z":0});
Rectangle spodek = new Rectangle("img/tube2.png", sw, sh, {"x":x, "y":sh+mezeray*pomer+y, "z":0});

vrch.onCollision((_){
  checkover();
});

spodek.onCollision((_){
  checkover();
});
game.addObject(spodek);
game.addObject(vrch);
var cp = new Checkpoint(sw, mezeray, {"x":x+sw, "y":y+sh, "z":0});
cp.onCollision((e){
  scoore++;
  querySelector("#scoore").text="SCOORE: ${scoore}";
  sounds[1].play();
  //THIS IS ERROR ZONE
  spawnt();
});
game.addObject(cp);

rnd = new Random();
rnd = rnd.nextInt(300);
rnd2 = new Random();
rnd2 = rnd2.nextInt(300);
var rnd3 = new Random();
rnd3 = new Random();
rnd3 = rnd3.nextInt(10);
Grab w;
if(rnd3 == 0 || rnd3 == 1 || rnd3 == 2){
  w = new Grab("img/cigarette.png", 600*pomer, 418*pomer, {"x":x+sw+rnd,"y":sh+mezeray*pomer+y-mezeray*pomer+rnd2-168*pomer, "z":0});
  w.scale(0.2);
  w.onCollision((c){
    smokescreen = true;
    smoketimer.cancel();
    smoketimer = new Timer(const Duration(milliseconds: 10000), (){
      smokescreen = false;
    });
    kucky.play();
    if(csong)
      cig.play();
    csong = false;
  });
  game.addObject(w);
}
else if(rnd3 == 3 || rnd3 == 4){
  w = new Grab("img/whiskey.png", 162*pomer, 398*pomer, {"x":x+sw+rnd,"y":sh+mezeray*pomer+y-mezeray*pomer+rnd2-168*pomer, "z":0});
  w.scale(0.2);
  w.onCollision((c){
    AudioElement pr = new AudioElement("sounds/yes.${koncovka}");
    pr.play();
    whiskey++;
    if(whiskey>=10 && whiskey<20){
      speedotoceni = 30;
      zhoupni();
    }
    else if(whiskey>=20 && whiskey<30){
      speedotoceni = 25;
      zhoupni();
    }
    else if(whiskey>=30 && whiskey<40){
      speedotoceni = 20;
      zhoupni();
    }
    else if(whiskey>=40 && whiskey<50){
      speedotoceni = 15;
      zhoupni();
    }
    else if(whiskey>=50 && whiskey<60){
     speedotoceni = 10;
      zhoupni();
    }
    else if(whiskey>=60 && whiskey<70){
      speedotoceni = 5;
      zhoupni();
    }
    else if(whiskey>=70 && whiskey<80){
      speedotoceni = 1;
      zhoupni();
    }
    querySelector("#scoore").text="SCOORE: ${scoore}";
  });
  game.addObject(w);
}
else if(rnd3 == 9){
  w = new Grab("img/jatra.png", 539*pomer, 521*pomer, {"x":x+sw+rnd,"y":sh+mezeray*pomer+y-mezeray*pomer+rnd2-168*pomer, "z":0});
  w.scale(0.1);
  w.onCollision((c){
    AudioElement pr = new AudioElement("sounds/yes.${koncovka}");
    pr.play();
    jatra++;
    document.cookie = "jatra=${jatra}; expires=Thu, 24 Dec 4000 00:00:00 GMT; path=/";
    querySelector("#jatracount").text = jatra.toString();
  });
  game.addObject(w);
 }
lastx = lastx+300*pomer+rnd;
}

字符串
class Game.dart

import 'dart:html';
  import 'dart:math';
  import 'dart:async';
  import 'Entity.dart';
  import 'Gravity.dart';
  import 'Rectangle.dart';
  import 'Camera.dart';
  import 'Checkpoint.dart';

  class Game {
    CanvasElement canvas;
    Gravity gravity;
    List<Entity> entities = new List();
    List<Rectangle> rectangles = new List();
    Camera camera;
    var leftSpace = 0;
    var topSpace = 0;
    var _onCollision;
    var _over = (_){};
    var _render = (_){};
    num _lastFrame = 0;
    bool isOver = false;

Game(this.canvas, this.gravity){
  window.animationFrame.then((e){this.render(e);});
}

void addEntity(Entity entita){
  this.entities.add(entita);
}

void addObject(Rectangle rectangle){
  this.rectangles.add(rectangle);
}

void render(num delta){
  num fps = 1000/(delta-this._lastFrame);
  this._lastFrame = delta;
  CanvasRenderingContext2D ctx = this.canvas.context2D;
  ctx.clearRect(0, 0, this.canvas.width+this.leftSpace.abs(), this.canvas.height+this.topSpace.abs());
  this._render(true);
  this.rectangles.forEach((s){
    ctx.fillStyle=s.color;
    if(s.hasColor()){
      ctx.fillStyle=s.color;
      ctx.fillRect(s.position["x"]-this.leftSpace,s.position["y"]-this.topSpace,s.width,s.height);
    }
    else{
      ctx.drawImageScaled(s.texture, s.position["x"]-this.leftSpace,s.position["y"]-this.topSpace,s.width,s.height);
    }
  });
  this.entities.forEach((e){
    e.move(fps);
    e.power["y"] += this.gravity.operate(e)*(60/fps);
    ctx.save(); 
    ctx.translate(e.position["x"]-this.leftSpace+e.width/2, e.position["y"]-this.topSpace+e.height/2);
    ctx.rotate(e.rotation* PI/180);
    ctx.drawImageScaled(e.img, -(e.width/2), -(e.height/2), e.width, e.height);
    ctx.restore(); 
  });
  collisionResponse();
  checkCollisions();
  if(!this.camera.fixed["x"])
    this.leftSpace = this.camera.target.position["x"]-this.canvas.width/2+this.camera.target.width/2;
  else
    this.leftSpace = this.camera.fixedPos["x"];

  if(!this.camera.fixed["y"])
    this.topSpace = this.camera.target.position["y"]-this.canvas.height/2+this.camera.target.height/2;
  else
    this.topSpace = this.camera.fixedPos["y"];
  this._render(false);
  ctx.closePath();
  window.animationFrame.then((e){this.render(e);});
}

void onCollision(e){
  this._onCollision = e;
}

void collisionResponse(){
  this.rectangles.forEach((s){
    num x1 = s.position["x"];
    num y1 = s.position["y"];
    num z1 = s.position["z"];
    num w1 = s.width;
    num h1 = s.height;

    this.entities.forEach((e){
      num rot = e.rotation * (PI / 180);
      num x2 = e.position["x"];
      num y2 = e.position["y"];
      num z2 = e.position["z"];
      num w2 = e.width;
      num h2 = e.height;
      if(x2>=x1-w2 && x2<=x1+w1 && y2>y1-h2 && y2<y1+h1 && z1==z2){
        s.collisionResponse(e);
        e.collision(s);
        s.collision(e);
      }
    });
  });
}

void checkCollisions(){
  List<Entity> kolize = new List();
  for(Entity e1 in this.entities){
    num x1 = e1.position["x"];
    num y1 = e1.position["y"];
    num z1 = e1.position["z"];
    num w1 = e1.width;
    num h1 = e1.height;

    for(Entity e2 in this.entities){
      if(e1 == e2 || (kolize.indexOf(e1) != -1 && kolize.indexOf(e2) != -1)) continue;
      num x2 = e2.position["x"];
      num y2 = e2.position["y"];
      num z2 = e2.position["z"];
      num w2 = e2.width;
      num h2 = e2.height;
      if(x2>=x1-w2 && x2<=x1+w1 && y2>y1-h2 && y2<y1+h1 && z1==z2){
        kolize.add(e1);
        kolize.add(e2);
      }
    }
  }
}

void over(){
  if(!this.isOver)
    this._over();
  this.isOver = true;
}

void onOver(e){
  this._over = e;
}

void onRender(f){
  this._render = f;
}
}


未捕获错误:在迭代过程中并发修改:'_GrowableList'的Instance(length:17). Stack Trace:#0 List.forEach(dart:core-patch/growable_array.dart:241)

1 Game.collisionResponse(FlappyBird/web/classes/Game.dart:83:28)

2 Game.render(FlappyBird/web/classes/Game.dart:62:22)

3 Game.render.(FlappyBird/web/classes/Game.dart:75:47)

4 _rootRunUnary(dart:zeroc/zone.dart:717)

5 _RootZone.runUnary(dart:zh/zone.dart:854)

6 _Future._propagateToListeners. PropagateValueCallback(dart:future_impl.dart:439)

7 _Future._propagateToListeners(dart:future_impl.dart:522)

8 _Future._complete(dart:future_impl.dart:303)

9 _SyncCompleter.complete(dart:future_impl.dart:44)

10 Window. animationFrame.(file:/E:/B/build/slave/dartium-win-full-stable/build/src/build/Release/obj/global_intermediate/blink/bindings/dart/dart/html/Window.dart:62)

异常:迭代期间并发修改:'_GrowableList'的示例(长度:17). undefined(undefined:0:0)
够了吗?有人知道怎么修理吗?谢谢回答。:)

wlp8pajw

wlp8pajw1#

此错误意味着您在迭代过程中正在向集合中添加或从集合中移除对象。这是不允许的,因为添加或移除项将更改集合大小并扰乱后续迭代。
错误可能来自以下行之一,您尚未发布其源代码:

s.collisionResponse(e);
 e.collision(s);
 s.collision(e);

字符串
我假设其中一个调用是在forEach期间从实体列表或矩形列表中删除一个项,这是不允许的。相反,您必须重新构造代码以删除列表迭代之外的项,可能使用removeWhere方法。
考虑以下从列表中删除奇数的尝试:

var list = [1, 2, 3, 4, 5];
list.forEach( (e) {
 if(e % 2 == 1) 
   list.remove(e);
});


这将失败,并出现并发修改异常,因为我们试图在列表迭代期间删除这些项。
然而,在列表迭代期间,我们可以标记要删除的项,然后使用removeWhere在批量操作中删除它们:

var list = [1, 2, 3, 4, 5];
var toRemove = [];

list.forEach( (e) {
 if(e % 2 == 1) 
   toRemove.add(e);
});

list.removeWhere( (e) => toRemove.contains(e));

6za6bjd0

6za6bjd02#

来自https://api.dartlang.org/stable/2.1.0/dart-core/Map/removeWhere.html的最新Dart版本2.1.0的新文档
执行

var map = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5};
   // delete the map entry that has the key 'a'
   map.removeWhere((key, value) => key == 'a');

字符串

w1e3prcc

w1e3prcc3#

尽量避免循环列表太多。使用这个:

list.removeWhere((element) => element % 2 == 1;

字符串

y53ybaqx

y53ybaqx4#

这样你就可以从动态列表中删除对象,并且在迭代过程中不会遇到异常并发修改,因为循环是由removeWhere自己完成的!

List data = [
    {
      "name":"stack"
    },
    {
      "name":"overflow"
    }
  ];
  
  data.removeWhere((item) => item["name"]=="stack");
  
  print(data);

字符串
输出

[{name: overflow}]

mm5n2pyu

mm5n2pyu5#

创建列表的副本并修改我有一个stockQty列表,但我想修改也将在某些条件下中断,所以我不能使用关于answers.so我做了一个列表的副本,并在它上面循环并修改差异。

var stockQty = [11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
  var purchaseQty = 15;
  var stockQrtCp = stockQty.toList();

  for (int sq in stockQrtCp) {
    if (purchaseQty >= sq) {
      print('Purchase Qty is greater than Stock Qty');

      stockQty.removeWhere((element) => element == sq);
      purchaseQty = purchaseQty - sq;
    } else {
      print('Purchase Qty is less than Stock Qty');
      sq = sq - purchaseQty;
      if (sq == 0) {
        stockQty.removeWhere((element) => element == sq);
      }
      break;
    }
  }

字符串

w8rqjzmb

w8rqjzmb6#

有点明显,但如果你有点累了,它可能不会那么明显:仔细检查你的函数的参数与Widget的变量之一不相似。
在我的例子中:

class _ManageUsersPageState extends State<ManageUsersPage> {
  late List<User> users;

...

void removeUser(List<User> users) { // worked after renaming the param to 'removedUsers'. this is the code before fixing the issue.
    List<User> tmp = users;

    for (User user in removedUsers) { // also made the change here, this is the code after renaming from 'users' to 'removedUsers' and fixing the issue.
      tmp.removeWhere((User item) => item.id == user.id);
    }
    setState(() => users = tmp);
  }
}

字符串

相关问题