Swift 3 Timer in a Class not firing

Viewed 2865

I have a class:

class GameManager {...

and within it I have this func:

func startGame() {

        msgTimer = Timer(timeInterval: 0.5, target: self, selector: #selector(typeMessage(_:)), userInfo: nil, repeats: true)

}

and the selector it calls:

@objc func typeMessage(_ sender:Timer) {

        if textCount > strInitText.characters.count {
            let strThisChar = strInitText[strInitText.index(strInitText.startIndex, offsetBy: textCount)]
            strDisplayText = strDisplayText + String(strThisChar)
            print(strDisplayText)
        }

    }

But the selector never gets called.

enter image description here

2 Answers

Change

msgTimer = Timer(timeInterval: 0.5, target: self, selector: #selector(typeMessage(_:)), userInfo: nil, repeats: true)

to

msgTimer = Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(typeMessage(_:)), userInfo: nil, repeats: true)

This timer needs to be scheduled on a run loop (via -[NSRunLoop addTimer:]) before it will fire.

And call it from the main thread as follows:

DispatchQueue.main.async { [weak self] in
        self?.msgTimer = Timer(timeInterval: 0.5, target: self, selector: #selector(self.typeMessage(_:)), userInfo: nil, repeats: true)
        RunLoop.current.add(self.msgTimer, forMode: RunLoopMode.commonModes)
}

However, I recommend you to use scheduledTimer in this instance to remove this step:

Creates a timer and schedules it on the current run loop in the default mode.

Be sure to invalidate the timer when you are done with it as follows:

self.msgTimer.invalidate()
Related