user3582537
user3582537

Reputation: 424

Is it safe (or good programming style) to initialize a lazy var with nil vars?

Let me explain a little better what I mean since it's kinda tricky to understand.

I'm creating a prototype for a videogame. Every level inherits the main rules from a SKScene called SceneLogic:

class SceneLogic: SKScene, SKPhysicsContactDelegate {
    // Set up the physics, the contacts, touches and so on...
}

class Level1: SceneLogic { }
class Level2: SceneLogic { }

Every level has its own .sks file which specifies the different icon to show in the HUD. In order to create a kind of "game engine" I thought to init every kind of graphics inside the SceneLogic class by lazy var and ignore them if the current level doesn't need it.

Let me explain with an example

class SceneLogic: SKScene, SKPhysicsContactDelegate {
    // Text, available only for level 1
    private lazy var textTopHUD = childNode(withName: "textTop") as! SKLabelNode

    // Icon, available only for levels 3,4,5
    private lazy var iconBottomHUD = childNode(withName: "iconBottom") as! SKSpriteNode

    // Icon, available only for level 2
    private lazy var iconLeftHUD = childNode(withName: "iconLeft") as! SKSpriteNode


    func initGame(level: Int) {
        switch mode {
            case 1: // Level 1
                textTopHUD.text = "Level 1"
            case 2: // Level 2
                iconLeftHUD.position = ....
        }
    }
}

The fact is: for level 1, iconBottomHUD is nil, for level 2 textTopHUD is nil... but the app doesn't crash since the var is lazy and it won't be called for some levels.

My question is: is it a good programming style? Is it safe to use lazy in this way?

Upvotes: 1

Views: 72

Answers (1)

Vollan
Vollan

Reputation: 1915

The thing about lazy properties is that it defers the execution of the initialization code. So in your case it doesn't really matter since they are actually nil. So you defer the init of nothing basically. If i were you i would basically either make it as a computed propert as such:

private lazy var iconBottomHUD: SKSpriteNode = {
      guard let node = childNode(withName: "iconBottom") as? SKSpriteNode else {
          fatalError()
      }
      return node
}

Or make it as @JavierRivarola mentioned, make it protocol based.

Upvotes: 1

Related Questions