ApplicationDidEnterBackground发生意外的崩溃:NSTimer
昨天,我问,因为我的计时器在后台有问题,我找到了一个解决方案,使其工作,但现在,当我的应用程序进入后台时遇到问题。在后台ApplicationDidEnterBackground发生意外的崩溃:NSTimer
运行:
backgroundTaskIdentifier = UIApplication.shared.beginBackgroundTask(expirationHandler: {
UIApplication.shared.endBackgroundTask(self.backgroundTaskIdentifier!)
})
这是我的计时器:
let interval = 0.01
timer = Timer.scheduledTimer(timeInterval: interval, target: self, selector:#selector(ViewController.updateTimer), userInfo: nil, repeats: true)
RunLoop.main.add(timer, forMode: RunLoopMode.commonModes)
这是我updateTimer功能:
func updateTimer() {
var j = 0
for _ in rows {
if (rows[j]["Playing"] as! Bool == true) {
rows[j]["time"] = (rows[j]["time"] as! Double + interval) as AnyObject
rows[j]["lastTime"] = (rows[j]["lastTime"] as! Double + interval) as AnyObject
}
if (rows[j]["lastTime"] as! Double > 60.0) {
min[j] += 1
rows[j]["lastTime"] = 0.00 as AnyObject
}
j += 1
}
}
在我applicationDidEnterBackground方法我调用这个函数:
func backgroundTimer() {
print("background") // This Print works fine
timer.invalidate() // Never works
interval = 1.00 // Crash when interval change from 0.01 to 1.00
timer = Timer.scheduledTimer(timeInterval: interval, target: self, selector:#selector(ViewController.updateTimer), userInfo: nil, repeats: true)
}
这是我的输出,当我的应用程序在后台输入:
的是双间隔。
In Info.plist我补充:应用程序不会在后台运行:NO。
让我知道我做错了什么?
编辑:行
初始化在viewDidLoad方法
let i: [String : AnyObject] = ["time": time as AnyObject, "Playing": false as AnyObject, "lastTime": 0.00 as AnyObject, "lapNumber": 0 as AnyObject, "min": 0 as AnyObject]
rows.append(i as [String : AnyObject])
你的基本问题似乎是事情是不是真的反对使用AnyObject
。它导致as! Bool
失败。
这是一个游乐场片段,它通过允许字典中的简单值获取存储的Bool值。
var rows: [[String : Any]] = []
let i: [String : Any] = ["time": time, "Playing": false, "lastTime": 0.00, "lapNumber": 0, "min": 0]
rows.append(i)
let playing = rows[0]["Playing"]
if let playing = playing as? Bool {
print("Bool")
} else {
print("Something else \(String(describing: playing))")
}
感谢您的回答。我测试过这种方式,但同样的结果时,appDidEnterBackground:'( – pierreafranck
如果您使用Phillip片段,然后你崩溃,因为解包零值应该消失...所以你应该有不同的崩溃现在... –
我找到了解决这个问题的方法。
使用NSNotification。
override func viewWillAppear(_ animated: Bool) {
NotificationCenter.default.addObserver(self, selector:#selector(ViewController.backgroundTimer), name:NSNotification.Name.UIApplicationDidEnterBackground, object: nil)
NotificationCenter.default.addObserver(self, selector:#selector(ViewController.backToForeground), name:NSNotification.Name.UIApplicationWillEnterForeground, object: nil)
}
func backgroundTimer(notification : NSNotification) {
self.timer.invalidate()
interval = 1.00
timer = Timer.scheduledTimer(timeInterval: interval, target: self, selector:#selector(ViewController.updateTimer), userInfo: nil, repeats: true)
RunLoop.main.add(timer, forMode: RunLoopMode.commonModes)
}
func backToForeground(notification: NSNotification) {
self.timer.invalidate()
interval = 0.01
timer = Timer.scheduledTimer(timeInterval: interval, target: self, selector:#selector(ViewController.updateTimer), userInfo: nil, repeats: true)
RunLoop.main.add(timer, forMode: RunLoopMode.commonModes)
}
不要忘了加上backgroundTaskIdentifier。
我想你正在使用AppDelegate mainVC方法来创建main的副本。这就是为什么你的计时器永远不会在你的ViewController无效。它在你的副本中是无效的。 看看这个答案:Pausing timer when app is in background state Swift
谢谢。这个答案解决我的问题!看看我的回答:) – pierreafranck
rows [j] [“Playing”]的值显然为零。 –
@AmeyaVichare感谢您的回答。它不能为零,它不是前景零,我不明白为什么它可以在后台 – pierreafranck
你如何初始化行?请张贴代码... –