是否可以在后台运行全局计时器?

时间:2016-04-06 16:05:31

标签: ios swift nstimer

对于我正在创建的应用程序,我希望在后台运行一个可以随时由应用程序中的任何文件启动和停止的计时器。

我想知道这是否可行,以及如何实现这一点。

我正在考虑使用全局变量(虽然我不确定这是否会在视图控制器之间持续存在)或者可能使用NSNotifications做些什么?

3 个答案:

答案 0 :(得分:7)

对于任何需要Swift 3版本的人:

class TimerModel: NSObject {
    static let sharedTimer: TimerModel = {
       let timer = TimerModel()
        return timer
    }()

    var internalTimer: Timer?
    var jobs = [() -> Void]()

    func startTimer(withInterval interval: Double, andJob job: @escaping () -> Void) {
        if internalTimer != nil {
            internalTimer?.invalidate()
        }
        jobs.append(job)
        internalTimer = Timer.scheduledTimer(timeInterval: interval, target: self, selector: #selector(doJob), userInfo: nil, repeats: true)
    }

    func pauseTimer() {
        guard internalTimer != nil else {
            print("No timer active, start the timer before you stop it.")
            return
        }
        internalTimer?.invalidate()
    }

    func stopTimer() {
        guard internalTimer != nil else {
            print("No timer active, start the timer before you stop it.")
            return
        }
        jobs = [()->()]()
        internalTimer?.invalidate()
    }

    @objc func doJob() {
        guard jobs.count > 0 else { return }
        for job in jobs {
            job()
        }
    }

}

我根据自己的需要做了一些改变。我添加了一个jobs数组,以便稍后我可以添加更多操作。我删除了那些fatalError来电。相反,定时器只会在startTimer()被调用两次时重新启动,并且在调用stopTimer()并且没有定时器时不执行任何操作。

答案 1 :(得分:6)

如果你需要这样的东西,你可以从任何地方访问它:

e.g:

class MyGlobalTimer: NSObject {

    let sharedTimer: MyGlobalTimer = MyGlobalTimer()
    var internalTimer: NSTimer?

    func startTimer(){
        guard self.internalTimer != nil else {
            fatalError("Timer already intialized, how did we get here with a singleton?!")
        }
        self.internalTimer = NSTimer.scheduledTimerWithTimeInterval(1.0 /*seconds*/, target: self, selector: #selector(fireTimerAction), userInfo: nil, repeats: true)
    }

    func stopTimer(){
        guard self.internalTimer != nil else {
            fatalError("No timer active, start the timer before you stop it.")
        }
        self.internalTimer?.invalidate()
    }

    func fireTimerAction(sender: AnyObject?){
        debugPrint("Timer Fired! \(sender)")
    }

}

这很粗糙,需要做很多工作,但它在1分钟的时间里才能实现。

要访问计时器,您可以执行以下操作:

    MyGlobalTimer.sharedTimer.startTimer()
    MyGlobalTimer.sharedTimer.stopTimer()
    let firedCounter = MyGlobalTimer.sharedTimer.numberOfTimesFired

修改

这是如何工作的:

MyGlobalTimer类是singleton class,通过调用MyGlobalTimer.sharedTimer来实例化。这实例化并且不能在application instance中再次实例化。从那里开始,[Grand Central Dispatch][1]用于处理事物的计时器和线程方面。

答案 2 :(得分:0)

阅读NSTimer参考以构建计时器。

全局变量是全局变量。它永远存在。通常,您不会仅创建全局变量,而是隐藏单例类中的所有功能。

通常说出你真正想要实现的目标是一个好主意,而不是说你认为你需要实现它。