Коллекция <__ NSArrayM: 0x76c11b0> была видоизменена при перечислении - PullRequest
7 голосов
/ 10 декабря 2011

Я относительно новичок в obj-c, поэтому я должен что-то упустить, но моя программа падает, когда враг сталкивается со стеной.Я находился там, где убираю врага из петли, пока в петле, но ради жизни я не могу понять, как это исправить.Мой код выглядит следующим образом:

(ошибка «[allEnemies removeObject: врагаType1];»)

// ВСЕГДА РАБОТАЕТ - (void) обновление: (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

Ответы [ 4 ]

24 голосов
/ 10 декабря 2011

Ну, так же, как и в случае ошибки, вы мутировали массив во время его перечисления.Самое простое решение - это сделать for (CCSprite *enemyType1 in [[allEnemies copy] autorelease]) Таким образом, вы перечисляете копию массива (это НЕ копирует элементы, а просто дает вам другой контейнер для перечисления их в) и все еще можете изменить изменяемый массив.

Вы не можете изменять контейнеры при перечислении их.

4 голосов
/ 10 декабря 2011

Проблема заключается в этой строке кода: [allEnemies removeObject:enemyType1]; вы перечисляете массив allEnemies и удаляете объект из массива в том же перечислении, которое вызывает проблему. Вы должны использовать временный массив для зацикливания, фактически изменяя (removeObject:) другой массив.

2 голосов
/ 04 августа 2017

Вы не можете удалять элементы из NSMutableArray во время итерации.

Есть несколько решений для этого:

  • Итерация копии массива

или

  • Используйте основанный на индексе цикл for вместо синтаксиса for each.

Не копирование массива экономит ваше выделение и несколько циклов ЦП:

for (int i = updatedLocalityArray.count-1 ; i >= 0 ; i--)
{
    NSString *test = updatedLocalityArray[i];
    if ([test isEqualToString:tableViewCell.textLabel.text])
    {
        [updatedLocalityArray removeObjectAtIndex:i];
        NSLog(@"%@ *****", updatedLocalityArray);
    }
}
0 голосов
/ 10 января 2017

Также это может произойти, когда вы добавляете объект в NSMutableArray и читаете запись из этого массива. И эти 2 задачи происходят в двух разных потоках. Как будто это происходит в фоновом потоке, а другое происходит в основном потоке. Так что будьте осторожны с потоками.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...