当应用程序后台运行或屏幕锁定时,DispatchQueue.global(qos:.default)继续,如何暂停?

时间:2019-04-01 04:32:04

标签: ios swift health-kit dispatch-queue

Swift新手:将Objective-C AppleHealth集成代码移植到由Flutter / Dart调用的Swift。当我对旧版Obj-C应用程序进行后台或锁定屏幕显示时,它几乎立即暂停了所有执行。 但是,在我的Swift代码端口中不会发生相同的行为,我在Swift中使用的是与旧版Obj-C应用中相同的DispatchQueue,

挂起之所以重要,是因为一旦用户锁定了iPhone屏幕,AppleHealth就会对其所有数据进行加密,并且不可用。 我的理解也是正确的,当您挂起DispatchQueue时,当前正在执行的块将完成,但随后的块将不会开始执行。 据我所知,Swift代码端口模仿了Obj-C逻辑,对于它为何表现不同或我可能缺少的任何提示都将不胜感激。

我正在使用

进行调度
DispatchQueue.global(qos: .default).async { 
/* code */ 
}

如果可以让新应用程序立即挂起我提交给DispatchQueue的所有执行代码,那么在后台或锁定屏幕时,我将非常高兴。

1 个答案:

答案 0 :(得分:2)

应用程序暂停后,无论正在运行的主队列还是后台global队列上的所有内容,也都将被暂停。

您是否正在应用程序中进行任何操作以使其在后台运行?例如,如果您通过Xcode调试器运行应用程序(例如,因此您可以查看print语句或其他内容),则会更改应用程序生命周期并使其在后台运行。 (Xcode是“观察者效果”?大声笑。)您是通过Xcode调试器运行此代码吗?

此外,如果您的应用启用了某些后台功能,也可以使该应用保持活动状态。

由于您无法通过Xcode调试器运行应用程序以监视应用程序生命周期,因此我将使用Unified Logging来演示监视应用程序进度的过程。使用统一日志记录,我可以从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中添加了类似的语句,以便在这里也可以看到生命周期事件。)无论如何,这就是控制台显示的内容:

Console

当“ tick 5”出现时我离开了我的应用程序,花了几秒钟才将其完全挂起,但是您可以看到在“ tick 7”和“ applicationDidEnterBackground”出现之后该应用程序停止运行。大约10秒钟后,我重新启动了该应用程序,这时您看到该应用程序恢复了活力,并在停止的位置继续滴答作响。

因此,如果您的应用仍在运行,则要么将其附加到Xcode调试器,要么可以使应用在后台运行。但是通常,当您离开应用程序时,该应用程序将被暂停,并且您会看到类似我上面概述的行为。

另外,有关使用统一日志记录,配置设备等的更多信息,请参阅WWDC 2016视频Unified Logging and Activity Tracing