所以我正在使用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}}解析为选择器。我不知道这个错误来自哪里。
答案 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];
}