Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/112.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 升级到SDK 5 for iOS后从NSMutableArray中删除对象会导致我的应用程序崩溃_Objective C_Ios_Xcode_Crash_Sigabrt - Fatal编程技术网

Objective c 升级到SDK 5 for iOS后从NSMutableArray中删除对象会导致我的应用程序崩溃

Objective c 升级到SDK 5 for iOS后从NSMutableArray中删除对象会导致我的应用程序崩溃,objective-c,ios,xcode,crash,sigabrt,Objective C,Ios,Xcode,Crash,Sigabrt,[编辑]我重新安排了如何从列表中删除obj。这就是它最初仍然导致相同错误的原因 这就是问题中的代码。我相信我已经将错误缩小到从_blocksnsmutableArray中删除对象的那一行。在代码的其他部分中,我有完全相同的代码,从同一数组中删除类似的对象。由于某种原因,当调用此函数时,会导致游戏崩溃。在我升级到支持iOSSDK5和armv7的最新XCode之前,它没有这个问题。在升级XCode之前,它工作得很好。我走进一个项目,项目就会从屏幕上消失。现在,当我得到一件物品时,它就崩溃了。任何帮助

[编辑]我重新安排了如何从列表中删除obj。这就是它最初仍然导致相同错误的原因

这就是问题中的代码。我相信我已经将错误缩小到从_blocksnsmutableArray中删除对象的那一行。在代码的其他部分中,我有完全相同的代码,从同一数组中删除类似的对象。由于某种原因,当调用此函数时,会导致游戏崩溃。在我升级到支持iOSSDK5和armv7的最新XCode之前,它没有这个问题。在升级XCode之前,它工作得很好。我走进一个项目,项目就会从屏幕上消失。现在,当我得到一件物品时,它就崩溃了。任何帮助都将不胜感激

-(void)itemCollision:(Collidable *)obj :(int)itemID :(int)objID: (bool)withPlayer{
[background removeChild:[obj getSprite] cleanup:YES];
[background removeChild:[obj getArrow] cleanup:YES];
[_blocks removeObject:obj];
//[obj release];
if(withPlayer){
    if(itemID == 1){
        [[SimpleAudioEngine sharedEngine] playEffect:@"Item2.mp3" pitch:1.0f pan:0.0f gain:0.3f];
        points += (10 + level * 22);
    }
}
}

错误消息是:“线程1:程序接收信号:“SIGARBRT”

下面是我调用itemCollision的代码:

-(bool) isCollision {
CCSprite *playerSprite = mob;//[mob getSprite];

CGRect playerRect = CGRectMake(playerSprite.position.x - (playerSprite.contentSize.width/2), 
                               playerSprite.position.y - (playerSprite.contentSize.height/2), 
                               playerSprite.contentSize.width, 
                               playerSprite.contentSize.height);

//Player Collision

BOOL collision = FALSE;

for (Block *block in _blocks) {
    CCSprite *blockSprite = [block getSprite];
    CGRect blockRect = CGRectMake(blockSprite.position.x - (blockSprite.contentSize.width/2), 
                                  blockSprite.position.y - (blockSprite.contentSize.height/2), 
                                  blockSprite.contentSize.width, 
                                  blockSprite.contentSize.height + 1 + [mob getSpeed]);
    if (CGRectIntersectsRect(blockRect, playerRect)) {
        if ([block getItemID] != 0) {
            [self itemCollision:block :[block getItemID] :[block getID] :TRUE];
            continue;
        }
        if(playerSprite.position.y > blockSprite.position.y){
            collision = TRUE;
        }
        if(collision) {
            [[SimpleAudioEngine sharedEngine] playEffect:@"squish.caf"];
            [self die];
            return TRUE;
        }
    }
}   
return FALSE;
}

下面是我如何从代码中其他地方的_块中删除对象。这是在重力计时器函数中:

NSMutableArray *blocksToDelete = [[NSMutableArray alloc] init];

for (Block *block in _blocks) {
    CCSprite *blockSprite = [block getSprite];
    //[block addSpeed:gravity];
    [block setPreX:blockSprite.position.x];
    [block setPreY:blockSprite.position.y];
    blockSprite.position = ccp(blockSprite.position.x, blockSprite.position.y - [block getSpeed]);
    if (blockSprite.position.y < -30 + blockSprite.contentSize.height / 2) {
        [blocksToDelete addObject:block];
    }
    if(blockSprite.position.y - blockSprite.contentSize.height < [block getArrow].position.y){
        [block getArrow].visible = FALSE;
    }
}

for (Block *b in blocksToDelete) {
    [_blocks removeObject:b];
    [background removeChild:[b getSprite] cleanup:YES];
    [background removeChild:[b getArrow] cleanup:YES];
    [b release];
}
NSMutableArray*blocksToDelete=[[NSMutableArray alloc]init];
用于(块*块中的块){
CCSprite*blockSprite=[block getSprite];
//[块速度:重力];
[block setPreX:blockSprite.position.x];
[block setPreY:blockSprite.position.y];
blockSprite.position=ccp(blockSprite.position.x,blockSprite.position.y-[block getSpeed]);
if(blockSprite.position.y<-30+blockSprite.contentSize.height/2){
[blocksToDelete addObject:block];
}
if(blockSprite.position.y-blockSprite.contentSize.height<[block getArrow].position.y){
[block getArrow].visible=FALSE;
}
}
用于(块中的块*b删除){
[_块移除对象:b];
[background removeChild:[b getSprite]清理:是];
[background removeChild:[b getArrow]清理:是];
[b]释放;
}

我在这些项到达被此函数删除的点之前访问它们。同样,在我升级我的XCode之前,这些代码已经运行了几个月。

如果数组在对象上有最后一次保留,则在您删除它时,它将被解除分配。您继续在方法的其余部分使用该对象,因此它需要保持活动状态。Certainl检查obj的retainCount以查看NSMUTABLEARRY是否具有最后一个retain是第一个开始的位置

如果我们目前假设情况就是这样,那么尝试以下替代方法:

-(void)itemCollision:(Collidable *)obj :(int)itemID :(int)objID: (bool)withPlayer
{
    [[obj retain] autorelease];
    [_blocks removeObject:obj];
    [background removeChild:[obj getSprite] cleanup:YES];
    [background removeChild:[obj getArrow] cleanup:YES];
    if(withPlayer){
        if(itemID == 1){
            [[SimpleAudioEngine sharedEngine] playEffect:@"Item2.mp3" pitch:1.0f pan:0.0f gain:0.3f];
            points += (10 + level * 22);
        }
    }
}
当调试器转到main.m时,通常是因为它在弹出自动释放池(一个没有调试符号的任务)时正在消亡,所以它转到最深的堆栈帧,它有源代码显示给您,在主线程上的自动释放池的情况下,它将是您的main()函数


您还应该尝试在Instruments中使用Zombies工具来运行此案例。这对跟踪此内容非常有帮助。

很难确切知道在您共享的代码示例范围之外发生了什么,但一个粗略的猜测是您的“obj”被过度释放。当您从t中删除它时,它会被释放一次他创建了一个数组,然后您将再次释放它。考虑到传入该对象时该对象的保留计数,这可能是合适的,也可能是不合适的

要开始故障排除,请尝试使用Instrument Zombie工具-这将帮助您观察它是否确实被过度放大

您还可以对以下内容进行注释:

[obj release]

查看这是否停止了错误(这可能是解决方案,也可能不是解决方案,但在任何情况下都应该是有见地的)。

是传入的对象(obj)是否在其他地方保留?当您从_blocks数组中删除它时,它的保留计数会减少1,我可能会冒昧地猜测它当时正在被释放。然后您再次调用它两次,然后再次释放,这肯定会表明您看到的错误类型。不要用“get”命名方法“前缀;只需将它们命名为
sprite
arrow
。它仍然会崩溃,并以相同的错误转到main。实际上,我添加了[obj版本],因为我想我忘记了,那是在最初的崩溃之后。在代码删除obj精灵和obj箭头图形,然后将其从_块列表中删除之前,没有释放它。但同样的错误仍然发生。我将发布向该线程调用itemCollision的代码。请看一看。我仍然不太确定如何使用僵尸工具,或者如何使用它来帮助我解决这个问题。我会调查的。如果您能继续帮助我解决这个问题,我将不胜感激。“当然,首先要检查obj的retainCount,看看NSMutableArray是否有最后一个retain。”这根本不是一个开始。重新计算是没有用的。别管它了。最初我没有发布那个obj,这就是我添加它的原因。在我添加它之前,我仍然得到那个错误。我编辑了上面的代码,以显示它最初是怎样的。我如何确切地使用僵尸工具来查看它是否已发布?我还添加了更多的代码,可以帮助您了解我的代码的作用。
-(void)itemCollision:(Collidable *)obj :(int)itemID :(int)objID: (bool)withPlayer
{
    [[obj retain] autorelease];
    [_blocks removeObject:obj];
    [background removeChild:[obj getSprite] cleanup:YES];
    [background removeChild:[obj getArrow] cleanup:YES];
    if(withPlayer){
        if(itemID == 1){
            [[SimpleAudioEngine sharedEngine] playEffect:@"Item2.mp3" pitch:1.0f pan:0.0f gain:0.3f];
            points += (10 + level * 22);
        }
    }
}
[obj release]