从运行循环中删除CADisplayLink时,游戏有时会崩溃

时间:2014-08-29 09:25:05

标签: ios xcode swift breakpoints cadisplaylink

每次玩游戏时都不会发生这种情况,也许每5或10次播放一次。当游戏结束时,我从运行循环中移除我的CADisplayLink(我用它来设置游戏区域的动画,有点像Flappy Bird中的管道)。然而,在少数情况下,它崩溃了。该行旁边有:

Thread 1: EXC_BAD_ACCESS (code=1, address=0x10)

这是代码:

func endGame(r : String) {

    UIView.animateWithDuration(0.4, delay: 0.2, options: .CurveLinear, animations: {
        self.scoreLabel.alpha = 0
        }, completion: {
            (finished: Bool) in
            self.scoreLabel.removeFromSuperview()
    });

    self.view.userInteractionEnabled = false
    reason = r
    println("Game Over!!!")

    //Crashes on this line
    blockUpdateDisplayLink.removeFromRunLoop(NSRunLoop.currentRunLoop(), forMode: NSRunLoopCommonModes)

    shiftDisplayLink.removeFromRunLoop(NSRunLoop.currentRunLoop(), forMode: NSRunLoopCommonModes)

    scoreTimer.invalidate()

    UIView.animateWithDuration(0.0001, delay: 0.7, options: .CurveLinear, animations: {

        }, completion: {
            (finished: Bool) in
            self.performSegueWithIdentifier("Game Over", sender: self)
    });
}

如果我注释掉第一个CADisplayLink部分,那么无论如何它都会崩溃。

这是堆栈跟踪:

enter image description here

其中有相同的"线程1"错误如上。

发生了什么事?

3 个答案:

答案 0 :(得分:5)

您必须使显示链接无效(而不是仅仅从运行循环中删除它们),因为如果它们在激活时处于运行中,它们仍可能尝试使用它们相关的运行循环。

答案 1 :(得分:3)

您要将CADisplayLink添加到哪个运行循环中?您可能需要使用NSRunLoop.mainRunLoop()代替。

此外,如果您的CADisplayLink仅在NSRunLoop上添加,则可以尝试拨打blockUpdateDisplayLink.invalidate()而不是删除它。


如果您在创建CADisplayLink对象的位置发布代码,则可以更轻松地追踪问题。

答案 2 :(得分:1)

我真的建议你用Instruments和NSZombies调试你的代码,找出你的内存问题。

Instruments

NSZombies