在我的iphone游戏中,当在ios 4.0模拟器上运行时一切正常。但是,当使用5.0模拟器或5.0+设备运行时,应用程序在第一级崩溃,留下错误:
由于未捕获的异常'NSGenericException'而终止应用程序,原因:
***集合< __ NSArrayM:0x1416eea0>在被列举的同时发生了变异 ***首先抛出调用堆栈:
(0x1d6a052 0x20d0d0a 0x1d69c21 0x6f8e 0x8bd48 0x94020 0xba169 0xbcee4 0x85a2db 0x85a1af 0x1d3e966 0x1d3e407 0x1ca17c0 0x1ca0db4 0x1ca0ccb 0x2702879 0x270293e 0x90fa9b 0x1f31 0x1eb5 0x1)
终止调用抛出异常(lldb)
我认为我已经将问题缩小到这段代码。我知道问题是在for-loop中移除对象但似乎无法找到解决方案。
这是我的代码:
//remove the projectile
for (CCSprite *projectile in projectilesToDelete) {
[_projectiles removeObject:projectile];
[self removeChild:projectile cleanup:YES];
}
[projectilesToDelete release];
//remove the projectile
for (CCSprite *targetDel in targetsToDelete) {
targetDel.position = ccp(-2000, -2000);
[self removeChild:targetDel cleanup:YES];
[_targets removeObject:targetDel];
}
[targetsToDelete release];
请帮忙,过去几天一直想弄清楚。
答案 0 :(得分:2)
简而言之,表达式:
for (OBJ * VAR in COLLECTION) {
使用名为快速枚举的技术。这里发生的是编译器在堆栈上插入一些隐藏的后备存储,并从可枚举的类型中请求一组元素。因为它一次抓取许多对象并对它们进行迭代,所以在枚举容器(COLLECTION
)时变错是错误的,因为堆栈区域和集合可能不同步。
解决方法是在您改变枚举内容时避免快速枚举 - 或者在某些情况下可以枚举副本。标准for(i;c;e)
循环不使用快速迭代 - 但for(in)
确实使用它。
改变程序以避免快速枚举错误的一种方法是:
// remove the projectile
while (projectilesToDelete.count) {
CCSprite * projectile = projectilesToDelete[0];
[_projectiles removeObject:projectile];
[self removeChild:projectile cleanup:YES];
}
[projectilesToDelete release];
// remove the projectile
while (targetsToDelete.count) {
CCSprite * targetDel = targetsToDelete[0];
targetDel.position = ccp(-2000, -2000);
[self removeChild:targetDel cleanup:YES];
[_targets removeObject:targetDel];
}
[targetsToDelete release];
答案 1 :(得分:1)
你的代码有问题,考虑到这个...... projectilesToDelete数组有3个元素(A,B,C)......
在第一次迭代中,删除对象(A)..在该数组计数变为2,即,数组内容将是(B,C)但它认为它是3(B,C,Nil)。
所以在枚举时修改了数组。所以它会给出一个例外。
将代码更改为此
// get array length
int count = projectilesToDelete. length;
// iterate through the array
for (int iter = 0; iter < count; inter++)
{
CCSprite *projectile = projectilesToDelete [iter];
[_projectiles removeObject:projectile];
[self removeChild:projectile cleanup:YES];
// decrement count
count--;
iter--;
}