MackTuesday
MackTuesday

Reputation: 543

Setting delegate results in crash, leaving it null doesn't

I'm trying to do something unusual out of sheer curiosity/masochism.

There's a tutorial called Swiftris. It's based on Swift 2, but I'm stuck with Swift 1 using Xcode 6. I can't use the debugger because it requires administrator privilege on the one machine I have access to. So I've put a text label on in my view controller for showing debug information.

So yeah, already this is a weird thing I'm trying to do. But I really want to learn this stuff.

So here's my code. There are two relevant files, GameController.swift and Swiftris.swift.

class GameViewController: UIViewController, SwiftrisDelegate {

    var scene: GameScene!
    var swiftris: Swiftris!

    var panPointReference:CGPoint?

    @IBOutlet weak var errorLabel: UILabel!

    override init() {
        super.init()
        //swiftris.delegate = self
    }

    required init(coder aDecoder: NSCoder) {
        //fatalError("init(coder:) has not been implemented")
        super.init(coder: aDecoder)
        swiftris.delegate? = self
    }

    // Leaving out the delegate functions here. I do implement them,
    // I'm just not showing them, and they don't seem to affect the
    // error. I've checked.

    func updateErrorLabel(s: String) {
        errorLabel.text = s
    }
}

and

protocol SwiftrisDelegate {
    func gameDidEnd(swiftris: Swiftris)
    func gameDidBegin(swiftris: Swiftris)
    func gameShapeDidLand(swiftris: Swiftris)
    func gameShapeDidMove(swiftris: Swiftris)
    func gameShapeDidDrop(swiftris: Swiftris)
    func gameDidLevelUp(swiftris: Swiftris)
    func updateErrorLabel(s: String)
}

class Swiftris {
    var blockArray:Array2D<Block>
    var nextShape:Shape?
    var fallingShape:Shape?
    var delegate:SwiftrisDelegate?

    var score = 0;
    var level = 1;

    init() {
        fallingShape = nil
        nextShape = nil
        blockArray = Array2D<Block>(columns: NumColumns, rows: NumRows)
        delegate?.updateErrorLabel("init")
    }

    func beginGame() {
        delegate?.updateErrorLabel("game beginning")
        if (nextShape == nil) {
            nextShape = Shape.random(PreviewColumn, startingRow: PreviewRow)
        }
        delegate?.gameDidBegin(self)
    }

    // Bunch of stuff excluded here that doesn't seem to matter
}

As you can see, in Swiftris I have a delegate that is for sending debug strings, and in GameViewController I set Swiftris's delegate to be myself so Swiftris can talk indirectly to my error label.

If I don't set it, there is no update to the error label, but there is also no crash, probably because that type is optional. If I do set, it crashes, complaining, "fatal error: unexpectedly found nil while unwrapping an Optional value". How can this thing be nil?

Upvotes: 0

Views: 92

Answers (1)

Andrej
Andrej

Reputation: 7426

You have to initialize swiftris before setting the delegate:

override init() {
        super.init()
        swiftris = Swiftris()
        swiftris.delegate = self
    }

Upvotes: 1

Related Questions