【问题标题】:Collection <__NSArrayM: 0x76c11b0> was mutated while being enumerated集合 <__NSArrayM: 0x76c11b0> 在枚举时发生了突变
【发布时间】:2011-12-10 18:19:36
【问题描述】:

我对 obj-c 比较陌生,所以我肯定遗漏了一些东西,但是当敌人与墙壁相撞时,我的程序会崩溃。我已经找到了从循环中移除敌人的位置,虽然在循环中,但是对于我的生活,我无法弄清楚如何修复它。 我的代码如下:

(错误是“[allEnemies removeObject:enemyType1];”)

//一直在运行 -(无效)更新:(ccTime)dt {

for (CCSprite *enemyType1 in allEnemies) { //for every attacking unit in allEnemies

    //Adjust the collison box for each enemey depending on the height of the enemy
    float a;
    float b;
    float yOne = (wall.contentSize.height-enemyType1.position.y);
    float yTwo = (wall.contentSize.height);
    float xTwo = 30;
    a = (xTwo*(yOne/yTwo)); // always < 1
    b = xTwo-a;             // always > 1


    //Create the altered collison box 
    CGRect enemyType1Rect = CGRectMake (
                enemyType1.position.x - (enemyType1.contentSize.width/2), 
                enemyType1.position.y - (enemyType1.contentSize.height/2), 
                enemyType1.contentSize.width+b, 
                enemyType1.contentSize.height
                                       );


    //If the enemey hits the wall, stop it, then add it to the attacking enemies array
    if (CGRectIntersectsRect(enemyType1Rect, wall.boundingBox)) {
        [enemyType1 stopAllActions];
        [allEnemies removeObject:enemyType1];
        [attackingEnemies addObject:enemyType1];            
    }


}
//Wall Collison END

【问题讨论】:

    标签: objective-c cocos2d-iphone


    【解决方案1】:

    好吧,正如错误所述,您在枚举数组时对其进行了变异。最简单的解决方法是 for (CCSprite *enemyType1 in [[allEnemies copy] autorelease]) 这样您就可以枚举数组的副本(这不会复制元素,只是给您另一个容器来枚举它们),并且仍然可以修改可变数组。

    枚举容器时不能修改容器。

    【讨论】:

    • 好的,你能解释一下它到底是做什么的吗? [allEnemies copy] 是否制作了数组的副本,并将其从原始“allEnemies”数组中删除。此外,当您将“autorelease”放在那里时,您不需要“[allEnemies removeObject:enemyType1];”对?抱歉,如果这听起来真的很愚蠢(我刚得到 xcode 4,而这一切都没有困扰我的 3)。编辑:所以我更改了那段代码,现在我得到:无法使用引导服务器注册 com.yourcompany.StromTheHouse。错误:未知错误代码。
    • 好吧,xcode 讨厌我。所以我想我得到“for (CCSprite *enemyType1 in [[allEnemies copy] autorelease])”,我没有得到引导错误,但是现在当我尝试在设备上测试时,我得到一个新错误:StormTheHouse [ 11129:707] cocos2d:无法在 CCTextureCache 中添加图像:wall.png 2011-12-10 11:02:05.888 StormTheHouse[11129:707] *** -[HelloWorld addChild:] 中的断言失败,/Users/rauhul /Desktop/Invasion/libs/cocos2d/CCNode.m:385 2011-12-10 11:02:05.890 StormTheHouse[11129:707] *** 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“参数必须是非-nil'
    • nvm 那些帖子我弄清楚发生了什么,我在我的代码中引用了 wall.png,但图像是 WALL.png,太感谢了
    • 也可以反向枚举,这样在迭代过程中删除对象是合法的。
    • @LearnCocos2D 这是因为执行 [array reverseEnumerator] 为您提供了另一个您正在处理的枚举器,本质上是一个不同的数组。
    【解决方案2】:

    问题在于这行代码:[allEnemies removeObject:enemyType1]; 您正在枚举数组allEnemies 并在导致问题的同一枚举中从数组中删除一个对象。您应该使用临时数组进行循环,同时实际改变(removeObject:)另一个数组。

    【讨论】:

      【解决方案3】:

      您无法在迭代 NSMutableArray 时删除项目。

      有几种解决方案:

      • 迭代数组的副本

      • 使用基于索引的for 循环而不是for each 语法。

      不复制数组可以节省分配和一些 CPU 周期:

      for (int i = updatedLocalityArray.count-1 ; i >= 0 ; i--)
      {
          NSString *test = updatedLocalityArray[i];
          if ([test isEqualToString:tableViewCell.textLabel.text])
          {
              [updatedLocalityArray removeObjectAtIndex:i];
              NSLog(@"%@ *****", updatedLocalityArray);
          }
      }
      

      【讨论】:

        【解决方案4】:

        当您将对象添加到 NSMutableArray 并从该数组中读取记录时,也可能发生这种情况。这两个任务发生在两个不同的线程中。就像一个发生在后台线程中,另一个发生在主线程上。对线程也非常小心。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-11-22
          • 1970-01-01
          • 2012-07-30
          • 2023-03-13
          • 1970-01-01
          • 1970-01-01
          • 2011-10-04
          相关资源
          最近更新 更多