72

This code worked on first XCode 6 Beta, but on latest Beta it's not working and gives such errors Must call a designated initializer of the superclass SKSpriteNode:

import SpriteKit

class Creature: SKSpriteNode {
  var isAlive:Bool = false {
    didSet {
        self.hidden = !isAlive
    }
  }
  var livingNeighbours:Int = 0

  init() {
    // throws: must call a designated initializer of the superclass SKSpriteNode
    super.init(imageNamed:"bubble") 
    self.hidden = true
  }

  init(texture: SKTexture!) {
    // throws: must call a designated initializer of the superclass SKSpriteNode
    super.init(texture: texture)
  }

  init(texture: SKTexture!, color: UIColor!, size: CGSize) {
    super.init(texture: texture, color: color, size: size)
  }
}

and that's how this class is initialiazed:

let creature = Creature()
creature.anchorPoint = CGPoint(x: 0, y: 0)
creature.position = CGPoint(x: Int(posX), y: Int(posY))
self.addChild(creature)

I'm stuck with it.. what will be the easiest fix?

Kosmetika
  • 20,774
  • 37
  • 108
  • 172

2 Answers2

98

init(texture: SKTexture!, color: UIColor!, size: CGSize) is the only designated initializer in the SKSpriteNode class, the rest are all convenience initializers, so you can't call super on them. Change your code to this:

class Creature: SKSpriteNode {
    var isAlive:Bool = false {
        didSet {
            self.hidden = !isAlive
        }
    }
    var livingNeighbours:Int = 0

    init() {
        // super.init(imageNamed:"bubble") You can't do this because you are not calling a designated initializer.
        let texture = SKTexture(imageNamed: "bubble")
        super.init(texture: texture, color: UIColor.clearColor(), size: texture.size())
        self.hidden = true
    }

    init(texture: SKTexture!) {
        //super.init(texture: texture) You can't do this because you are not calling a designated initializer.
        super.init(texture: texture, color: UIColor.clearColor(), size: texture.size())
    }

    init(texture: SKTexture!, color: UIColor!, size: CGSize) {
        super.init(texture: texture, color: color, size: size)
    }
}

Furthermore I would consolidate all of these into a single initializer.

Epic Byte
  • 33,840
  • 12
  • 45
  • 93
  • I managed to fix this with overriding convenience ``init`` - http://stackoverflow.com/a/25164687/2117550 – Kosmetika Aug 07 '14 at 08:09
  • @grfs: Very helpful answer, but I'm curious: where is it documented that this is the only designated initializer for SKSpriteNode? – drewblaisdell Aug 24 '14 at 07:32
  • @drewblaisdell https://developer.apple.com/library/prerelease/ios/documentation/SpriteKit/Reference/SKSpriteNode_Ref/index.html#//apple_ref/occ/instm/SKSpriteNode/initWithTexture:color:size: – Epic Byte Aug 24 '14 at 18:09
  • 3
    @drewblaisdell If you look at how the initializers are declared, you will see the convenience initializers are marked with the convenience keyword, and the designated initializers are not. It's not that clear because you need to click on every initializer and look at the way it's declared. Hopefully they develop a better way of showing it in the future. – Epic Byte Aug 24 '14 at 18:12
  • 4
    I wish I could up vote this twice as this answer just made the correlation between convenience initializers and super inits click for me. Thanks @Epic Byte – Shawn J. Molloy May 30 '15 at 23:33
  • Good answer but assuming you want it to work like the existing convenience initializers, then the color parameter should default to SKColor.whiteColor() not UIColor.clearColor(). – SwampThingTom Nov 08 '15 at 19:12
14

Crazy stuff.. I don't fully understand how I managed to fix it.. but this works:

convenience init() {
    self.init(imageNamed:"bubble")
    self.hidden = true
}

init(texture: SKTexture!, color: UIColor!, size: CGSize) {
    super.init(texture: texture, color: color, size: size)
}

add convenience to init and remove init(texture: SKTexture!)

saurabh
  • 6,687
  • 7
  • 42
  • 63
Kosmetika
  • 20,774
  • 37
  • 108
  • 172