Swift Xcode "EXC_BAD_INSTRUCTION"

Cseal69 picture Cseal69 · Apr 10, 2015 · Viewed 7.8k times · Source

when I try to run my game I get this

fatal error: unexpectedly found nil while unwrapping an Optional value

with the Thread error

EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)" 

This happens on this line of code

HighscoreLbl.text = NSString(format: "Highscore : %i", Highscore)

In my gamescene

import SpriteKit

class GameScene: SKScene, SKPhysicsContactDelegate {


var movingGround: CSMovingGround!
var hero: CSHero!
var cloudGenerator: CSCloudGenerator!
var wallGenerator: CSWallGenerator!
var wall: CSWall!
var scoreLabel = UILabel()
var score = Int()
var isStarted = false

var heroCategory: UInt32 = 1<<1
var wallCategory: UInt32 = 1<<2
var groundCategory: UInt32 = 1<<2
var invisCategory: UInt32 = 1<<3
let walls = CSWall()

var HighscoreLbl: UILabel!
var Highscore = 0


override func didMoveToView(view: SKView) {
    backgroundColor = UIColor(red: 159.0/255.0, green: 201.0/255, blue: 244.0/255.0, alpha: 1.0)

    /*
    let backgroundTexture = SKTexture(imageNamed: "background.png")
    let backgroundImage = SKSpriteNode(texture: backgroundTexture, size: view.frame.size)
    backgroundImage.position = view.center
    addChild(backgroundImage)
    */

    var HighscoreDefault = NSUserDefaults.standardUserDefaults()

    if (HighscoreDefault.valueForKey("Highscore") != nil){
        Highscore = HighscoreDefault.valueForKey("Highscore") as NSInteger!
        HighscoreLbl.text = NSString(format: "Highscore : %i", Highscore)
    }


    // add ground
    movingGround = CSMovingGround(size: CGSizeMake(view.frame.width, kCSGroundHeight))
    movingGround.position = CGPointMake(0, view.frame.size.height/2)

    self.addChild(movingGround)

    // add hero
    hero = CSHero()
    hero.position = CGPointMake(70, movingGround.position.y + movingGround.frame.size.height/2 + hero.frame.size.height/2)
    hero.physicsBody = SKPhysicsBody(rectangleOfSize: hero.size)
    hero.physicsBody?.dynamic = true
    hero.physicsBody?.allowsRotation = false
    hero.physicsBody!.collisionBitMask = heroCategory | wallCategory
    hero.physicsBody!.contactTestBitMask = wallCategory | heroCategory | groundCategory
    self.addChild(hero)
    hero.breathe()


    // add cloud generator
    cloudGenerator = CSCloudGenerator(color: UIColor.clearColor(), size: view.frame.size)
    cloudGenerator.position = view.center
    addChild(cloudGenerator)
    cloudGenerator.populate(7)
    cloudGenerator.startGeneratingWithSpawnTime(5)

    // add wall generator

    wallGenerator = CSWallGenerator(color: UIColor.clearColor(), size: view.frame.size)
    wallGenerator.position = view.center
    wallGenerator.physicsBody = SKPhysicsBody(edgeLoopFromRect : wallGenerator.frame)
    wallGenerator.physicsBody?.dynamic = true
    wallGenerator.physicsBody?.categoryBitMask = wallCategory
    wallGenerator.physicsBody?.affectedByGravity = false
    wallGenerator.physicsBody!.collisionBitMask = 0
    wallGenerator.physicsBody!.contactTestBitMask = invisCategory

    self.addChild(wallGenerator)


    let ground1 = SKSpriteNode(color: UIColor.clearColor(), size: CGSizeMake(view.frame.size.width, 15))
    ground1.position = view.center
    ground1.physicsBody = SKPhysicsBody(rectangleOfSize: ground1.size)
    ground1.physicsBody!.dynamic = false
    ground1.physicsBody!.affectedByGravity = false
    ground1.physicsBody!.categoryBitMask = groundCategory
    ground1.physicsBody!.collisionBitMask = groundCategory | heroCategory
    self.addChild(ground1)

    let ground2 = SKSpriteNode(color: UIColor.clearColor(), size: CGSizeMake(view.frame.size.width, 20))
    ground2.position = CGPointMake(284, 98)
    ground2.physicsBody = SKPhysicsBody(rectangleOfSize: ground2.size)
    ground2.physicsBody!.dynamic = false
    ground2.physicsBody!.affectedByGravity = false
    ground2.physicsBody!.categoryBitMask = groundCategory
    ground2.physicsBody!.collisionBitMask = groundCategory | heroCategory
    self.addChild(ground2)

    let ground3 = SKSpriteNode(color: UIColor.clearColor(), size: CGSizeMake(20, 500))
    ground3.position = CGPointMake(100, 100)
    ground3.physicsBody = SKPhysicsBody(rectangleOfSize: ground3.size)
    ground3.physicsBody?.dynamic = true
    ground3.physicsBody?.affectedByGravity = false
    ground3.physicsBody?.categoryBitMask = invisCategory
    ground3.physicsBody!.collisionBitMask = 0
    ground3.physicsBody!.contactTestBitMask = wallCategory
    self.addChild(ground3)

    physicsWorld.contactDelegate = self

    scoreLabel = UILabel(frame: CGRect(x: 10, y: 15, width: 100, height: 20))
    scoreLabel.backgroundColor = UIColor(red: 0.6, green: 0.1, blue: 0.1, alpha: 0)
    scoreLabel.textColor = UIColor.blackColor()
    self.view?.addSubview(scoreLabel)

    HighscoreLbl = UILabel(frame: CGRect(x: 10, y: 0, width: 300, height: 20))
    HighscoreLbl.textColor = UIColor.blackColor()
    self.view?.addSubview(HighscoreLbl)


}


func start() {
    isStarted = true
    hero.stop()
    hero.startRunning()
    movingGround.start()

}

func addScore() {
    score++
    scoreLabel.text = NSString(format: "Score : %i", score)
    if (score > Highscore){
        Highscore = score
        HighscoreLbl.text = NSString(format: "Highscore : %i", Highscore)

        var HighscoreDefault = NSUserDefaults.standardUserDefaults()
        HighscoreDefault.setValue(Highscore, forKey: "Highscore")
        HighscoreDefault.synchronize()
    }

}

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    if !isStarted {
        start()
        score = 0
        scoreLabel.text = NSString(format: "Score : %i", score)
        wallGenerator.startGeneratingWallsEvery(0.5)
    } else {
        hero.flip()
    }


}

func didBeginContact(contact: SKPhysicsContact) {
    var firstBody = SKPhysicsBody()
    var secondBody = SKPhysicsBody()
    if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
        firstBody = contact.bodyA
        secondBody = contact.bodyB
    } else {
        firstBody = contact.bodyB
        secondBody = contact.bodyA
    }

    if firstBody.categoryBitMask == invisCategory || secondBody.categoryBitMask == invisCategory {
        self.addScore()
    }


    if (firstBody.categoryBitMask & UInt32(heroCategory)) != 0 && (secondBody.categoryBitMask & UInt32(wallCategory)) != 0 {
        self.addScore()
        wallGenerator.removeFromParent()
        let reveal = SKTransition.flipHorizontalWithDuration(0.5)
        let scene = GameOverScene(size: self.size, won: false)
        self.view?.presentScene(scene, transition: reveal)
        scoreLabel.removeFromSuperview()
    }


}


override func update(currentTime: CFTimeInterval) {
    /* Called before each frame is rendered */

}
}

Answer

ravron picture ravron · Apr 10, 2015

This line:

HighscoreLbl.text = NSString(format: "Highscore : %i", Highscore)

implicitly unwraps HighscoreLbl before you initialize it, later:

HighscoreLbl = UILabel(frame: CGRect(x: 10, y: 0, width: 300, height: 20))
HighscoreLbl.textColor = UIColor.blackColor()
self.view?.addSubview(HighscoreLbl)

This causes your crash. You must initialize the variable before attempting to use it.