如何在进入后台后杀死NSTimer并在应用恢复活动后创建新的计时器?

时间:2014-12-13 03:04:14

标签: ios iphone swift timer nstimer

所以我正在使用Swift构建一个简单的iOS应用程序。我需要在应用程序进入后台后杀死NSTimer,并在应用再次激活后创建一个新的NSTimer

最初我的解决方案是在主控制器文件中的ViewDidLoad()中创建applicationDidEnterBackground()类的计时器。这会导致我的应用中出现错误。

我想我需要在 AppDelegate.swift 中使用import UIKit import CoreData class TodoTableViewController: UITableViewController, NSFetchedResultsControllerDelegate {.... ... ... override func viewDidLoad() { super.viewDidLoad() var fetchRequest = NSFetchRequest(entityName: "Todo") let sortDescriptor = NSSortDescriptor(key: "dayleft", ascending: true) fetchRequest.sortDescriptors = [sortDescriptor] if let managedObjectContext = (UIApplication.sharedApplication().delegate as AppDelegate).managedObjectContext { fetchResultController = NSFetchedResultsController(fetchRequest:fetchRequest, managedObjectContext: managedObjectContext, sectionNameKeyPath: nil, cacheName: nil) fetchResultController.delegate = self var e: NSError? var result = fetchResultController.performFetch(&e) todos = fetchResultController.fetchedObjects as [Todo] if result != true { println(e?.localizedDescription) } } var timer = NSTimer.scheduledTimerWithTimeInterval(10, target: self, selector:"update", userInfo:nil, repeats: true) } ... } 来终止计时器。但我不确定如何做到这一点。我应该在 AppDelegate.swift 或主控制器中创建计时器类吗?我不知道Swift文件如何共享类。

我在线搜索了解决方案,但这些帖子都太旧了,解决方案是用Objective-C编写的。

我绝对是初学者。所以我希望有人可以在Swift中解释它。

以下是我的主控制器中的代码 TodoTableViewController.swift

import UIKit
import CoreData

class TodoTableViewController: UITableViewController, NSFetchedResultsControllerDelegate {
...

var timer = NSTimer.scheduledTimerWithTimeInterval(10, target: self, selector:"viewDidLoad", userInfo:nil, repeats: true)

func update(){
    .....
}

override func viewDidLoad() {
    super.viewDidLoad()
    ...

    let notificationCenter = NSNotificationCenter.defaultCenter()

    notificationCenter.addObserver(self, selector: "didEnterBackground", name: "UIApplicationDidEnterBackgroundNotification", object: UIApplication.sharedApplication())

    notificationCenter.addObserver(self, selector: "didBecomeActive", name: "UIApplicationWillEnterForegroundNotification", object: UIApplication.sharedApplication())   
}


func didEnterBackground() {
    timer.invalidate()
}
func didBecomeActive() {
    var timer = NSTimer.scheduledTimerWithTimeInterval(10, target: self, selector:"update", userInfo:nil, repeats: true)
}

...
}

如果我要在 AppDelegate.swift 中使计时器无效,我怎样才能将计时器引用到我在 TodoTableViewController.swift 中创建的计时器?或者我应该把所有与计时器相关的代码放在 AppDelegate.swift 中?


更新

我尝试过使用NSNotificationCenter,这是我的代码。

didBecomeActive()

由于计时器是在didEnterBackground()中声明的,因此在timer中存在错误:没有名为“timer”的成员。如果我在didBecomeActive()之外声明update(),就像我上面发布的代码一样,则会在调用中出现“额外参数'选择器'时出错”。我已经将函数{{1}}解析为选择器。我不知道这个错误来自哪里。

2 个答案:

答案 0 :(得分:10)

更新了您的代码并添加了一些评论:

class TodoTableViewController: UITableViewController, NSFetchedResultsControllerDelegate 

   //better to instantiate timer inside viewDidLoad
   var timer: NSTimer!

   func update(){ }

   override func viewDidLoad() {
      super.viewDidLoad()
      startTimer()

      let notificationCenter = NSNotificationCenter.defaultCenter()

      //UIApplicationDidEnterBackgroundNotification & UIApplicationWillEnterForegroundNotification shouldn't be quoted
      notificationCenter.addObserver(self, selector: "didEnterBackground", name: UIApplicationDidEnterBackgroundNotification, object: nil)
      notificationCenter.addObserver(self, selector: "didBecomeActive", name: UIApplicationWillEnterForegroundNotification, object: nil)   
   }

   func didEnterBackground() {
      self.timer.invalidate()
   }

   func didBecomeActive() {
      startTimer()
   }

   func startTimer() {
      self.timer = NSTimer.scheduledTimerWithTimeInterval(10, target: self, selector:"update", userInfo:nil, repeats: true)
   }
}

另请注意NSTimer强烈保留target。所以当关闭viewcontroller时 - 定时器应该是无效的。或者会发生内存泄漏,永远不会销毁TodoTableViewController

答案 1 :(得分:1)

回答Objective-C,但我认为它在Swift中非常相似。

在ViewDidLoad中添加两个通知:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didEnterBackground) name:UIApplicationDidEnterBackgroundNotification object:[UIApplication sharedApplication]];

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didBecomeActive) name:UIApplicationWillEnterForegroundNotification object:[UIApplication sharedApplication]];

然后将其添加到视图控制器类中。

- (void)didEnterBackground{
[_timer invalidate];
}

- (void)didBecomeActive{
_timer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(update) userInfo:nil repeats:YES];
}