【问题标题】:Keep running NSTimer switching Background and Foreground继续运行 NSTimer 切换背景和前景
【发布时间】:2015-02-12 18:58:23
【问题描述】:

我正在尝试创建一个由用户在前台手动启动的 NSTimer,并且正如预期的那样完美运行:

timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("updateCounter"), userInfo: nil, repeats: true)

updateCounter() 只是在 UI 中更新 UILabel。 现在我想要实现的是在用户离开应用程序时也让它运行。我用谷歌搜索了一些东西并找到了这段代码(我用 Swift 翻译了):

func applicationDidEnterBackground(application: UIApplication) {
            var bgTask = UIBackgroundTaskIdentifier()
            bgTask = UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler { () -> Void in
                UIApplication.sharedApplication().endBackgroundTask(bgTask)
            }
            // Start the long-running task and return immediately.
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { () -> Void in



               var vc = TimerViewController()
               // Fire some methods
               UIApplication.sharedApplication().endBackgroundTask(bgTask)
               bgTask = UIBackgroundTaskInvalid
               });
        }

据我所知,基本上,当应用程序进入后台时,我可以从我的 TimerViewController() 的新实例中触发一些方法,该实例应该在后台阶段处理 NSTimer

现在这是否意味着我需要使用此 vc 或其他方法中的方法,该方法从前台停止的确切时间开始另一个 NSTimer(因为应用程序进入后台)?

如果是,当用户再次打开应用程序时恢复我的第一个NSTimer(再次表示前台:D)我应该如何表现?停止第二个NSTimer 并使用更新的计数器恢复第一个?

实际上,即使是解决方案的草图也值得赞赏,我只是想弄清楚如何处理这种情况。

进一步的问题:如果上面写的结果是正确的,我该如何管理viewcontroller 的实例以获取timer_value(类似secondsLeft 的令牌)时发生从背景到前景的切换,反之亦然?

【问题讨论】:

  • 你有没有尝试使用 [[NSRunLoop currentRunLoop] addTimer:loop forMode:NSRunLoopCommonModes];

标签: ios xcode swift background nstimer


【解决方案1】:

与其尝试在后台维护NSTimer(这不可能超过大约 10 分钟),您想要做的是记录计时器何时启动并将其保存在NSUserDefaults 中。您仍然可以每秒更新一次计时器,但只需根据开始时间重新计算标签(请记住,NSTimer 不保证它会按时运行;它可能由于多种原因而迟到并且您会漂移)。

现在没有理由在后台运行。当您的视图控制器出现在屏幕上时 (viewDidAppear:),只需根据保存在 NSUserDefaults 中的开始时间再次更新标签。

iOS 中无法无限期地在后台运行。这是设计使然。但是,当您不在屏幕上时,您也没有理由浪费系统资源来尝试更新您的 UI。到时候就更新吧。

【讨论】:

  • 这种方法有很多优点,特别是如果您正在编写计时器或秒表类型的应用程序。您可以轻松地使用此模式使您的“计时器”即使在设备重新启动后仍然存在。如果您尝试完成倒计时,请考虑使用 UILocalNotification 在时间到期时触发。
  • 感谢您的回答,非常清楚!现在,如果我想要倒计时 30 分钟并向用户发送通知,因为@JeremyPope 说我必须使用 UILocalNotification 对吗?但是这种情况下定时器是如何处理的呢?
  • NSTimer 的唯一用途是当您的视图在屏幕上时。 UILocalNotification 只有在您处于后台时才真正需要。所以他们处理不同的情况。
  • 本地通知可用于通知用户他们的计时器已过期,即使他们在另一个应用程序中。
  • 我会试试这个!谢谢你们俩
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-03
  • 1970-01-01
  • 2012-05-30
  • 1970-01-01
相关资源
最近更新 更多