当一个应用程序被挂起时,任何正在运行的东西,无论是在主队列还是后台global
队列,也会被挂起。
您是否在应用程序中执行任何操作以使其在后台运行?例如,如果您通过 Xcode 调试器运行应用程序(例如,您可以查看print
语句或其他内容),它会更改应用程序生命周期并使其在后台运行。(Xcode“观察者效应”?哈哈。)例如,你是通过 Xcode 调试器运行这个吗?
此外,如果您的应用启用了某些后台功能,这也可以使应用保持活动状态。
由于您无法通过 Xcode 调试器运行应用程序来查看应用程序生命周期,因此我将演示使用统一日志记录来监视我的应用程序进度的过程。使用统一日志记录,我可以从我的 macOS 控制台监控我的 iPhone 上的这些日志语句,甚至根本不需要运行 Xcode。
考虑类似的事情:
import UIKit
import os.log
private let log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "ViewController")
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
os_log("viewDidLoad", log: log, type: .debug)
startTask()
}
func startTask() {
DispatchQueue.global().async {
var i = 0
while true {
let start = Date()
while Date().timeIntervalSince(start) < 1 { }
os_log("tick %d", log: log, type: .debug, i)
i += 1
}
}
}
}
(注意,通常你不应该这样旋转,但我这样做是为了有一个故意让 CPU 保持忙碌的进程。)
所以我然后:
- 安装在我的设备上,
- 退出 Xcode,
- 启动 macOS 控制台应用程序,
- 在控制台应用程序中,我使用“操作”»“包含调试消息”启用了调试日志记录,
- 过滤日志,所以我只能看到来自我的子系统的活动(我个人总是使用我的包标识符),并且
- 直接在我的 iOS 设备上运行我的应用程序。
当我挂起应用程序时,我们可以清楚地看到应用程序停止(包括在后台队列上运行的此任务)。(显然,除了上面的os_log
消息之外,我还在我的AppDelegate
.
当“tick 5”出现时我离开了我的应用程序,在应用程序完全暂停之前需要几秒钟,但你可以看到应用程序在“tick 7”和“applicationDidEnterBackground”出现后停止运行。大约 10 秒后我重新启动了应用程序,此时您会看到应用程序恢复生机并继续滴答作响,就在它停止的地方。
因此,如果您的应用程序仍在运行,要么它附加到 Xcode 调试器,要么您有一些东西使应用程序在后台运行。但一般来说,当你离开一个应用程序时,它会被暂停,你会看到我上面概述的行为。
顺便说一句,有关使用统一日志记录、配置设备等的更多信息,请参阅 WWDC 2016 视频统一日志记录和活动跟踪。