NSTimer scheduledTimerWithTimeInterval - 不调用函数

NSTimer scheduledTimerWithTimeInterval - not calling funciton

我想 运行 在后台设置一个计时器。所以我创建了一个单例。

问题是在设定的5.0秒后,没有调用函数timeEnded()。 Xcode 提议在函数前加上@Objc(像这样:@Objc func timeEnded() {...)来解决一些问题(虽然我不明白是什么)。但它仍然没有调用该函数。有什么想法吗?

class TimerService {
    static let instance = TimerService()
    var internalTimer: NSTimer?

    func startTimer() {
        guard internalTimer != nil else {
            return print("timer already started")
        }
        internalTimer = NSTimer.scheduledTimerWithTimeInterval(5.0, target: self, selector: #selector(TimerService.timeEnded), userInfo: nil, repeats: false)
    }

    func timeEnded() {
        //NSNotificationCenter.defaultCenter().postNotificationName("timerEnded", object: nil)
        print("timer Ended")
    }
}

选择器是 Objective-C 的一项功能,只能与公开给动态 Obj-C 运行时的方法一起使用。你不能有一个纯 Swift 方法的选择器。

如果您的 class 继承自 NSObject,那么它的 public 方法会自动暴露给 Obj-C。由于您的 class 不是从 NSObject 继承的,因此您必须使用 @objc 属性来指示您希望将此方法公开给 Obj-C,以便可以使用 Obj-C 选择器调用它。

#selector() 是 Swift 2.2 中的新语法。它允许编译器检查您尝试使用的选择器是否确实存在。旧语法已弃用,将在 Swift 3.0.

中删除

您从未真正启动计时器,因为您的 startTimer() 函数总是 return 在到达您创建计时器的代码行之前。

在您的 guard 语句中,您仅在 internalTimer != nil 时继续执行该函数,但您设置计时器的唯一位置是 该语句之后.因此,您的计时器永远不会被创建并且 internalTimer 将永远是 nil.

这应该可以解决您的问题:

func startTimer() {
    guard internalTimer == nil else {
        return print("timer already started")
    }
    internalTimer = NSTimer.scheduledTimerWithTimeInterval(5.0, target: self, selector: #selector(TimerService.timeEnded), userInfo: nil, repeats: false)
}