简体   繁体   中英

Permanently disable Timers - iOS Swift 4

I am trying to completely reload a Game Scene after the player failed to achieve the goal after 10 seconds.

I use the scheduled Timer function to countdown the seconds.

func runTimer() {
    time.timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(GameScene_1.updateTimer)), userInfo: nil, repeats: true)
}

Here is the called function from above:

@objc func updateTimer() {
    if time.seconds == 0 {
        //Lost the game - reload
        reloadLevel()

    }else{

        ...
    }
}

When I reload the Game with the following code, the countdown speed gets too high.

func reloadLevel(){
    //Reset
    time.seconds = 10
    time.timer = nil

    //Reload Level
    let newScene = GameScene_1(fileNamed: "GameScene_1")
    newScene?.scaleMode = self.scaleMode
    let animation = SKTransition.flipVertical(withDuration: 2)
    self.view?.presentScene(newScene!, transition: animation)
}

This runTimer() - function is only called once in my project and this is when the user ends to touch the screen. Before this point, everything is fine, but after that, it seems like several timers start to countdown at once.

Does someone know, how I can reload the scene in a "clean" way, so that nothing from the scene before is saved? ...or how I can permanently stop/delete the previous timer?

I tried to write the following three statements at in my opinion relevant places (in the didMove - function, before the scene changes...), to solve this problem, but obviously nothing helped.

Thank you in advance!

time.timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(GameScene_1.updateTimer)), userInfo: nil, repeats: true)

This creates a retain loop. The view controller is retaining the timer (via time I assume; it's not exactly clear what time is) and the timer is retaining the view controller (via target: self ). Even if that weren't true, the timer is retained also by the run loop, so time.timer = nil doesn't stop it.

It's not clear what time is here, so I'm not precisely certain what the code you need is, but the tool you want is invalidate() . You need to call timer.invalidate() whenever the view leaves the screen ( viewWillDisappear ), and anytime you replace the timer. I generally use something like:

var timer: Timer? {
    willSet {
        timer?.invalidate()
    }
}

This way, anytime you assign to timer , the old timer will be invalidated (which is almost always what you meant).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM