1

I've ran my spritekit game on the following devices: iPhone 5s, iPhone 4s, iPad air and iPad mini. The app runs and all the devices except the 4s. On the 4s the app crashes when the app transitions to scenes that include SKPhysicsContactDelegate, for example:

class PlayScene: SKScene, SKPhysicsContactDelegate, ADBannerViewDelegate {


 enum ColliderType: UInt32 {

    case  narrowCategory = 1
    case  bigCategory = 2
    case  smallCategory = 4
    case  roundCategory = 8

}

var narrow = SKSpriteNode(imageNamed: "Narrow")
var big = SKSpriteNode(imageNamed: "Big")

override func didMoveToView(view: SKView) {
   ........ }

The error message that comes up when the app crashes is: thread 1 exc_breakpoint (code=exc_arm_breakpoint, subcode = 0xe7ffdefe).

Initially the error stopped the app at this line where I add in the background music (which doesn't make any sense to me because this line is also within one of the other scenes with no SKPhysicsContactDelegate and yet it runs smoothly):

   var backgroundMusicURL: NSURL = NSBundle.mainBundle().URLForResource("LevelOne", withExtension: "wav")!

When I commented out the background music the app then crashed at this line

   NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("addPlay"), name: "AddPlay", object: nil)

After I comment it out again the error jumps to this line

    narrow.physicsBody?.mass = 0.0001

then this

     narrow.physicsBody?.allowsRotation = true

and the error keeps moving as I comment out any lines that it previously crashed at. The app stops crashing once I remove the background music and all the functions that I call into my didMoveToView(view: SKView) that adds or modifies new or existing spritenodes, an example of one of these functions is below:

func addDiamond() {



    var diamond = SKSpriteNode(texture: diamondTexture)




    diamond.name = "diamond"
    diamond.physicsBody = SKPhysicsBody(circleOfRadius: diamond.size.width/2)
    diamond.zPosition = 1
    diamond.physicsBody?.mass = 0.01
    diamond.physicsBody?.allowsRotation = true
    diamond.physicsBody?.dynamic = true
    diamond.physicsBody?.affectedByGravity = false

    diamond.setScale(0.75)

    diamond.physicsBody?.categoryBitMask = diamondCategory
    diamond.physicsBody?.contactTestBitMask = laserCategory
    diamond.physicsBody?.collisionBitMask = laserCategory






    // setting the position 

    let minX = diamond.size.width/2
    let maxX = self.frame.size.width - diamond.size.width/2
    let rangeX = maxX - minX
    let positionX: CGFloat = round(CGFloat(arc4random()) % CGFloat(rangeX) + CGFloat(minX))

    let minY = self.frame.size.height/5
    let maxY = self.frame.size.height * 0.4
    let rangeY = maxY - minY
    let positionY: CGFloat = round(CGFloat(arc4random()) % CGFloat(rangeY) + CGFloat(minY))

    diamond.position = CGPointMake(positionX, positionY)

    // setting the rotation 

    let minR = 0
    let maxR = 6
    let rangeR = maxR - minR
    let positionR: CGFloat = round(CGFloat(arc4random()) % CGFloat(rangeR) + CGFloat(minR))
    diamond.zRotation = positionR
    // set animation

    let hold = SKAction.waitForDuration(4)
    let remove = SKAction.removeFromParent()

    diamond.runAction(SKAction.sequence([hold,remove]))



    // animation of bubble

    let minDur = 6
    let maxDur = 8
    let rangeDur = maxDur - minDur
    let durationOne = Int(arc4random()) % Int(rangeDur) + Int(minDur)
    let durOne = NSTimeInterval((Double(durationOne)/25))


    var animateArray:NSMutableArray = NSMutableArray()
    for i in 1...1500 {

        animateArray.addObject(SKAction.rotateByAngle(0.2, duration: 0.01))
      //animateArray.addObject(SKAction.rotateByAngle(-0.2, duration: 0.5))


    }


    diamond.runAction(SKAction.sequence(animateArray))
    animateArray.addObject(SKAction.removeFromParent())

     addChild(diamond)

}

this is added using the line below in the viewdidload

    diamondTimer = NSTimer.scheduledTimerWithTimeInterval(10, target: self, selector: Selector("addDiamond"), userInfo: nil, repeats: true) 

Scenes that do not use SKPhysicsContactDelegate run fine on the 4s. I also tested the 4s on the simulator and it seemingly crashes when you get to scenes using SKPhysicsContactDelegate but unlike the device an error doesn't come up, the device just blacks out and crashes without any debug sessions on xcode...does anyone have the faintest idea about what is going on here?

appsaa
  • 43
  • 8
  • Check that narrow.physicsBody is not nil. Other than that, try to narrow it down by commenting out more code. If the error seems to keep moving to different places, you may have stumbled into one of Swift's crash bugs. – CodeSmile Jan 27 '15 at 18:19
  • Yeah after I comment out the line (or in some cases the whole section involving the line) where it previously crashed, the error does seem to just keep moving to different places...So if this is one of swift's crash bugs, do you know if is there anything I could do about it? – appsaa Jan 27 '15 at 19:21
  • if it is one of those bugs, the only thing you can do is to report it, and try out every new (even beta) version of xcode. Personally I don't expect Swift to be in a production ready state before Xcode 6.3 (mainly because debugging swift code can lead to xcode crashing consistently, especially when using non-Apple frameworks). – CodeSmile Jan 27 '15 at 20:54

1 Answers1

3

The problem was that I was using this line to place my nodes in a random position.

 let durationOne = Int(arc4random()) % Int(rangeDur) + Int(minDur)

I suppose the problem with this line was that it in 32-bit devices (like the 4s) the device couldn't handle the size of the random number and it caused a crash. When I replaced that line with :

 let durationOne = UInt32(arc4random()) % UInt32(rangeDur) + UInt32(minDur)

the problem stopped and the device ran smoothly. Although I have no idea why the error message did not target this line and kept moving about to irrelevant lines...anyway i hope that helps anyone with a similar problem!

appsaa
  • 43
  • 8