集合<__ NSArrayM:0x76c11b0>在枚举时发生了变异

问题描述:

我对obj-c比较陌生,所以我必须错过某些东西,但是当敌人与墙壁碰撞时,我的程序会崩溃。我找到了从循环中移除敌人的位置,而在循环中,但对于我的生活,我无法弄清楚如何修复它。 我的代码如下:集合<__ NSArrayM:0x76c11b0>在枚举时发生了变异

(错误是 “[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 

好吧,就像错误状态一样,您在枚举枚举时突变了数组。最简单的修复方法是做for (CCSprite *enemyType1 in [[allEnemies copy] autorelease])这样你就可以枚举数组的副本(这不会复制元素,只是给你另一个枚举它们的容器),并且仍然可以修改可变数组。

枚举时不能修改容器。

+0

好了,你能解释正是做什么。 [allEnemies copy]是否复制数组,并将其从原始“allEnemies”数组中移除。另外当你把“autorelease”放在那里时,你不需要有“[allEnemies removeObject:enemyType1];”对?对不起,如果这听起来真的很愚蠢(我刚刚得到了xcode 4,而且这还不是我3中的烦恼)。 编辑: 所以我改变了这段代码,现在我得到: 无法注册com.yourcompany.StromTheHouse与引导服务器。错误:未知的错误代码。 – user1091516

+0

好吧,xcode讨厌我。所以我想我得到了“for(CCSprite * enemyType1 in [[allEnemies copy] autorelease])”,我没有得到引导程序错误,但现在当我尝试在设备上测试时,出现一个新错误: StormTheHouse [11129:707] cocos2d:无法添加图片:墙。png in CCTextureCache 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',原因:'参数必须是非零' – user1091516

+0

nvm这些帖子我想出了什么是继续,我在我的代码中引用了wall.png,但图像是WALL.png,Thx soooo – user1091516

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

此外,这可能会发生,当你添加一个对象到NSMutableArray中,并从该数组中读取记录。这两个任务发生在两个不同的线程中。就像一个正在后台线程中发生,另一个正在主线程中发生。对线程也要小心。

迭代它时,您不能从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); 
    } 
}