0

I have an "AFK" detector in my app. However it's behaving very strangely and I really don't know why. Note I have other timers in the app however they have their own variable names and I don't cross-them at any time. I think they're all independent unless they all somehow run on the same thread or some "under-the-hood" shenanigans happens. Here is the code that manages it:

func resetRoundtimer() {
        roundTime = 75
    }

    @objc func updateRoundTimer() {
        if roundTime < 0.5 {
            print ("Round time is up!")
            timeRemaining.invalidate()
            skipTurnDueToInactivity()
            timerActivity.stopAnimating()
            skipTurn = true
        } else {
            roundTime -= 0.5
        }
        timerLabel.text = String(format: "%.01f", roundTime)
    }

    func startRoundTimer() {
        timeRemaining = Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(self.updateRoundTimer), userInfo: nil, repeats: true)
        timerActivity.startAnimating()
    }

This triggers "Skip due to inactivity" which is another function that also counts how many times you've been AFK and if there are 3 you should be disconnected for being AFK too long:

func skipTurnDueToInactivity() {
    timeRemaining.invalidate()
    print ("YOU HAVE BEEN AFK LONG ENOUGH! SKIPPING TURN! \(afkSkips)")
    if afkSkips == 3 {
        print ("YOU HAVE BEEN AFK 3 TIMES, DISCONNECTING YOU FROM MATCH DUE TO INACTIVITY")
        print("You ded son!")
        sendData(key: DID_ELIMINATE, stage: currentStage, int: nil, double: nil, player: nil, notes: nil)
        didEliminatePlayer(playerDed: GKLocalPlayer.localPlayer())
    } else {
        afkSkips += 1
    }
}

This is the console output:

Round time is up!
YOU HAVE BEEN AFK LONG ENOUGH! SKIPPING TURN! 0
AFK hostQ
Round time is up!
YOU HAVE BEEN AFK LONG ENOUGH! SKIPPING TURN! 1
AFK hostQ
Round time is up!
YOU HAVE BEEN AFK LONG ENOUGH! SKIPPING TURN! 2
AFK hostQ
Round time is up!
YOU HAVE BEEN AFK LONG ENOUGH! SKIPPING TURN! 3
YOU HAVE BEEN AFK 3 TIMES, DISCONNECTING YOU FROM MATCH DUE TO INACTIVITY
You ded son!

if I clearly "invalidated" the timer why does it keep firing the skipTurn function?

pacification
  • 5,838
  • 4
  • 29
  • 51
dvd.Void
  • 339
  • 1
  • 5
  • 21
  • Possible duplicate of [swift invalidate timer doesn't work](https://stackoverflow.com/questions/34507799/swift-invalidate-timer-doesnt-work) – RajeshKumar R Jan 30 '18 at 14:25
  • What else is calling `skipTurnDueToInactivity` since `if roundTime < 0.5` is false coz `roundTime` is `75` – Inder Kumar Rathore Jan 30 '18 at 15:14
  • no one else is calling skipturnduetoinactivity. I CTRL F the project and its only mentioned twice (this call & the definition). It gets called when the roundTime < 0. – dvd.Void Jan 30 '18 at 15:49

1 Answers1

0

According to Apple's docs:

The object to which to send the message specified by aSelector when the timer fires. The timer maintains a strong reference to target until it (the timer) is invalidated.

So you may have come across a nice retain cycle (meaning the Timer holds a strong reference to self and self holds a strong reference to Timer), depending on how you declared the timeRemaining remaining variable.

Try setting it to:

weak var timeRemaining: Timer?
Bell App Lab
  • 818
  • 6
  • 14