NSTimer not firing when NSMenu is open in Swift

2019-01-09 12:59发布

问题:

I have a timer that runs to restart an alarm once it goes off.

alarm = NSTimer.scheduledTimerWithTimeInterval(
    60 * minutesConstant + secondsConstant,
    target:self,
    selector: Selector("endSession"),
    userInfo: nil,
    repeats:false)

Its selector function sets a mode flag, and calls the original function that set the alarm with new minutes and seconds constants, and also sends a user notification that the session has restarted.

I have a menu item that gets updated with the remaining time

So I've been opening it to check that my alarm does indeed restart, and that the notification shows once it hits zero. It works, but when I have the menu open and it gets down to zero it just stays at 0:00 and the timer doesn't fire until I click off the menu at which point it immediately shows the notification and resets the timer like intended.

How can I force the timer to fire when the menu is open? It's not a big deal but I don't want the user to be confused with the session just hangs if they watch the timer go down.

回答1:

You just have to add your timer to the main runloop as follow:

Swift 4.2

RunLoop.main.add(timer, forMode: .common)

Swift 3

RunLoop.main.add(alarm, forMode: .commonModes)

Swift 2.x

NSRunLoop.mainRunLoop().addTimer(alarm, forMode: NSRunLoopCommonModes)