Iphone Cocos2d NSMutable数组在枚举时发生了变异

Iphone Cocos2d NSMutable数组在枚举时发生了变异,iphone,objective-c,cocos2d-iphone,nsmutablearray,collision,Iphone,Objective C,Cocos2d Iphone,Nsmutablearray,Collision,我一直在做一个游戏,在某一点上我移除敌人的游戏对象没有问题(现在它们是从CCSprite中派生出来的,我知道这不是最好的方法) 但我不确定在将目标添加到targetsToDelete后,当程序尝试从\u targets中删除child时,我更改了什么使其崩溃 我试着四处移动,我只是不知道在创建阵列时如何添加或编辑阵列。。。任何帮助或建议都会很好 实际上,如果你有任何关于如何最好地创建游戏敌人的建议,你会将NSObject或CCNode子类化吗?我听说要把它们分成组件类,但我不知道它们的意思 //

我一直在做一个游戏,在某一点上我移除敌人的游戏对象没有问题(现在它们是从
CCSprite
中派生出来的,我知道这不是最好的方法)

但我不确定在将目标添加到
targetsToDelete
后,当程序尝试从
\u targets
中删除child时,我更改了什么使其崩溃

我试着四处移动,我只是不知道在创建阵列时如何添加或编辑阵列。。。任何帮助或建议都会很好

实际上,如果你有任何关于如何最好地创建游戏敌人的建议,你会将
NSObject
CCNode
子类化吗?我听说要把它们分成组件类,但我不知道它们的意思

//Projectile Target collision

-(void)update:(ccTime)dt {

    for (spygot *target in _targets) {
        CGRect targetRect = CGRectMake(
                                       target.position.x - (target.contentSize.width/2),
                                       target.position.y - (target.contentSize.height/2),
                                       target.contentSize.width,
                                       target.contentSize.height);

        //Collision Detection Player
        CGRect playerRect2 = CGRectMake(
                                        _controlledSprite.position.x - (_controlledSprite.contentSize.width/2),
                                        _controlledSprite.position.y - (_controlledSprite.contentSize.height/2),
                                        _controlledSprite.contentSize.width,
                                        _controlledSprite.contentSize.height);

    NSMutableArray *projectilesToDelete = [[NSMutableArray alloc] init];
    for (Projectile *projectile in _projectiles) 
    {           
        NSMutableArray *targetsToDelete = [[NSMutableArray alloc] init];

        CGRect projectileRect = CGRectMake(
                                           projectile.position.x - (projectile.contentSize.width/2),
                                           projectile.position.y - (projectile.contentSize.height/2),
                                           projectile.contentSize.width,
                                           projectile.contentSize.height);
        BOOL monsterHit = FALSE;

        if (CGRectIntersectsRect(projectileRect, targetRect))
        {
            NSLog(@"hit");
            target.mhp = target.mhp - 1;
            monsterHit = TRUE;

            if (target.mhp <= 0)
            {
                [targetsToDelete addObject:target];
            }
        }


        for (spygot *target in targetsToDelete) 
        {
            [self removeChild:target cleanup:YES];
            [_targets removeObject:target];
        }

        if (monsterHit)
        {
            [projectilesToDelete addObject:projectile];
        }

        [targetsToDelete release];
    }

    for (Projectile *projectile in projectilesToDelete) 
    {
        [_projectiles removeObject:projectile];
        [self removeChild:projectile cleanup:YES];

    }
    [projectilesToDelete release];
}
//射弹-目标碰撞
-(无效)更新:(ccTime)dt{
用于(间谍*目标在_目标中){
CGRect targetRect=CGRectMake(
target.position.x-(target.contentSize.width/2),
target.position.y-(target.contentSize.height/2),
target.contentSize.width,
目标、内容大小、高度);
//碰撞检测播放器
CGRect playerRect2=CGRectMake(
_controlledSprite.position.x-(_controlledSprite.contentSize.width/2),
_controlledSprite.position.y-(_controlledSprite.contentSize.height/2),
_Controlled Sprite.contentSize.width,
_Controlled Sprite.contentSize.height);
NSMutableArray*ProjectleStodelet=[[NSMutableArray alloc]init];
用于(射弹*射弹中的射弹)
{           
NSMUTABLEARRY*targetsToDelete=[[NSMUTABLEARRY alloc]init];
CGRect PROJECTLERECT=CGRectMake(
射弹位置x-(射弹内容尺寸宽度/2),
射弹位置y-(射弹内容尺寸高度/2),
1.contentSize.width,
射弹(尺寸、高度);
BOOL monsterHit=FALSE;
if(CGRectIntersectsRect(ProjectlerRect,targetRect))
{
NSLog(@“命中”);
target.mhp=target.mhp-1;
怪物命中=真;

如果(target.mhp看起来你粘贴的代码都是在
for
循环中迭代
\u targets
。变量
target
是如何初始化的?

通常当我遇到这种错误时,这是因为我的代码在一个块中,或者以其他方式在一个模糊的线程上。你有多确定这段代码不会同时运行多次

您可以尝试将其包装为以下内容:

dispatch_async(dispatch_get_main_queue(), ^{
    // do everything here.
});

至于使用CCSprite处理游戏敌人对象的建议,我的建议是在出现问题时进行修复。你现在看到了问题吗?过早优化几乎和一开始就做错事一样糟糕。在项目结束时,你会更好地知道你应该如何更早地完成它。;)

我想您知道在迭代数组时无法从数组中删除元素。这就是为什么要使用
targetsToDelete
数组

但在我看来,你确实很快就可以移除目标

试试这个:
完成主循环的迭代,并完成对targetsToDelete数组的目标收集,并且只有在主循环完成后才能删除目标。

您编写了“当[尝试]从_目标中删除child时崩溃”。为了清楚起见,您的意思是违规行是
[自删除child:target cleanup:YES];
还是
[[u targets removeObject:target]
?是的,我意识到发生崩溃是因为我有一个单独的计划程序启动新目标。当同时从
\u目标
中删除
目标时,它总是会崩溃。很高兴知道问题发生在哪里。但不知道如何解决它,我如何确保它们不会同时运行?问题是什么局部变量
target
(出现在您粘贴的代码中)在哪里初始化?
-(void)addTarget{spygot*target=(nil);target=[spygot meowgot];[_targetsaddobject:target];[self addChild:target z:16];}
,这由
-(void)游戏逻辑:(ccTime)dt{[self addTarget]
这是在init
[自调度:@selector(gameLogic:)interval:1.0]中调度的;
那么您在问题中发布的代码在您的
-addTarget
方法中?您可以编辑您的问题以添加您发布的代码显示在其中的完整方法吗?好的。在该
-update
方法中,您在问题中发布的代码中显示的局部变量
target
如何(例如,在中,这一行
target.mhp=target.mhp-1;
)已初始化?我担心的是,您发布的所有代码都可能被包装在
for(spygot*target in_targets){/**/}
块中。