【发布时间】:2014-10-24 21:52:47
【问题描述】:
我目前正在为 iPhone 编写游戏,有时我会随机崩溃并显示标题中的错误。
我已经研究了很多,它可能与泄漏(?)内存问题有关。我问过的人告诉我,这可能与添加一个 nil 对象有关。我设置了异常断点和 NSZombies,但它们都没有识别崩溃,也没有给我发生崩溃的确切代码行。
经过一些崩溃测试后,我注意到大多数情况下,当 touchesBegan 方法或 didBeganContact 方法处于活动状态时会发生这种情况。
touchesBegan 方法和 didBeginContact 方法的代码如下:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if (touchEnabled == YES){
firstTouch++;
if (firstTouch == 1){
SKAction* removeFade = [SKAction removeFromParent];
SKAction* startFade = [SKAction fadeAlphaTo:0 duration:0.5];
SKAction* fadeSeq = [SKAction sequence:@[startFade, removeFade]];
[startScreen runAction:fadeSeq completion:^{
startScreenRemoved = YES;
[self gameCountdown];
touchToShoot = YES;
}];
}
if (firstTouch == 2){
weaponActivated = YES;
}
if (gameOver == YES){
[self removeAllActions];
[self removeAllChildren];
[bgPlayer stop];
touchToShoot = NO;
SKScene* gameScene = [[GameScene alloc] initWithSize:self.size];
SKTransition *doors = [SKTransition doorsOpenVerticalWithDuration:1];
[self.view presentScene:gameScene transition:doors];
gameOver = NO;
}
}
if (touchToShoot == YES) {
[self weaponParticle];
touchToShoot = NO;
[self performSelector:@selector(enableTouchToShoot) withObject:nil afterDelay:0.3]; //-enableTouchToShoot{} = touchToShoot = YES;
}
//Pause Button
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
SKNode *node = [self nodeAtPoint:location];
if ([node.name isEqualToString:@"pauseButton"]) {
[self pauseMenu];
}
else if ([node.name isEqualToString:@"continue"]) {
self.paused = NO;
pauseBG.hidden = YES;
pauseText.hidden = YES;
backm.hidden = YES;
cont.hidden = YES;
//Damit unsichtbare Buttons nicht während dem Spiel gedrückt werden
backm.zPosition = -100;
cont.zPosition = -100;
}
else if ([node.name isEqualToString:@"backtomenu"]) {
self.paused = NO;
[self displayAlert];
}
}
-(void)didBeginContact:(SKPhysicsContact *)contact{
if (contact.bodyA.categoryBitMask == shipCategory) {
//Explosion Animation
SKAction* wait =[SKAction waitForDuration:0.5];
SKAction* fadeOut = [SKAction scaleTo:0.0 duration:1];
remove = [SKAction removeFromParent];
explodeSequenceGO =[SKAction sequence:@[fadeOut,wait,remove]];
ExplosionPath = [[NSBundle mainBundle] pathForResource:@"Explosion" ofType:@"sks"];
Explosion = [NSKeyedUnarchiver unarchiveObjectWithFile:ExplosionPath];
Explosion.position = CGPointMake(contact.bodyA.node.position.x, contact.bodyA.node.position.y);
[self addChild:Explosion];
[Explosion runAction:explodeSequenceGO];
[contact.bodyA.node removeFromParent];
[contact.bodyB.node removeFromParent];
[shipSmoke removeFromParent];
[player1 removeFromParent];
touchEnabled = NO;
[self gameOver];
}
if (contact.bodyA.categoryBitMask == enemyCategory || contact.bodyB.categoryBitMask == enemyCategory) {
//Explosion Animation
SKAction* wait =[SKAction waitForDuration:0.5];
SKAction* fadeOut = [SKAction scaleTo:0.0 duration:1];
remove = [SKAction removeFromParent];
explodeSequenceGO =[SKAction sequence:@[fadeOut,wait,remove]];
ExplosionPath = [[NSBundle mainBundle] pathForResource:@"Explosion" ofType:@"sks"];
Explosion = [NSKeyedUnarchiver unarchiveObjectWithFile:ExplosionPath];
Explosion.position = CGPointMake(contact.bodyA.node.position.x, contact.bodyA.node.position.y);
[Explosion runAction:explodeSequenceGO];
[self addChild:Explosion];
[contact.bodyA.node removeFromParent];
[contact.bodyB.node removeFromParent];
hitCount++;
[self scoreChange:100];
}
if (hitCount>39) {
[self eLevel2];
}
}
有人看到过错吗?我非常感谢任何提示,因为我正在寻找这个错误数周......
编辑:崩溃只是指向“main”函数,这根本没有帮助
在每个线程“动作”中,它只指向 Assembly(?) 代码:
就像我说的,我尝试通过各种调试工具(NSZombies、MemoryTool、Exceptional Breakouts 等)分析崩溃,但它们都没有给我有用的信息。当应用程序崩溃时,调试工具会停止记录,但不会显示任何故障或崩溃结果。
【问题讨论】:
-
哪一行给出了错误?像这样丢掉一堆代码然后让我们筛选它不是很有效。
-
您可以从 Xcode 中复制并粘贴调用堆栈以及几乎所有其他内容作为文本,只需选择它并按 Cmd+C。图像使事情难以阅读。一个提示:如果您呈现一个新场景,请确保没有其他代码以相同的方法运行。您应该在那里添加一个返回,否则您可能会在 0.3 秒后在当前场景上执行选择器,而它可能已经被释放。
标签: objective-c crash sprite-kit exc-bad-access