2

首先,如果您认为我的问题很愚蠢,我想说声抱歉,我是 iOS 和多线程的新手,只想了解事情的进展。据我所知didEnterBackground,这是 iOS 在应用程序暂停之前调用的最后一个函数,应用程序有大约 5 秒的时间从它返回,否则 iOS 将终止应用程序。我目前正在考虑这种情况 - 我有一些任务正在后台线程(例如网络下载)上发生,它的完成块发生在主线程上。像这样

fun downloadData() {
  Downloader.download(url: "someUrl") { [weak self] in // download is on the background thread
    DispatchQueue.main.async { [weak self] in // switch to main
      // do some stuff
    }
  }
}

downloadData()当前正在后台线程上运行,用户点击主页按钮,应用程序进入后台并被didEnterBackground调用。而主线程在didEnterBackground downloadData完成下载时执行代码并调用它的完成并将新任务推入主线程队列。那么在这种情况下会发生什么?由于 from 的代码didEnterBackground是在暂停之前可以执行的最后一个代码,所以它的完成块会发生什么downloadData,它是否也会在暂停之前(之后didEnterBackground)执行,或者一旦用户返回应用程序就会执行,或者它会被丢弃吗?或者这种情况根本不可能?感谢您的帮助,如果我的问题不正确,再次抱歉。

4

1 回答 1

1

首先,我建议你考虑这个文件提供Apple。该文档本身很清楚,但我将通过它来提取与您的问题相匹配的重要信息。

在本文档中,Apple 明确表示每个暂停的 UI 任务都将被丢弃,您不应将新任务提交到 Dispatch 队列,您应该暂停当前队列并尽快释放资源。

当应用程序应该被停用时,有两个步骤:

  1. 系统调用应用程序applicationWillResignActive(_:)方法(或sceneWillResignActive(_:) 如果您使用sceneDelegate
  2. 然后 UIKit 调用applicationDidEnterBackground(_:)方法(或sceneDidEnterBackground(_:)

在第一步中,UIKit 会通知您停用,这意味着在几次之后,应用程序将进入后台。在执行此步骤时,您必须保存所有敏感数据。

在此步骤中,如果您已暂停 UI 任务,则所有这些任务都将被丢弃。

当需要暂时中断应用程序时,系统还会停用应用程序——例如,显示系统警报

在这一步中,你必须暂停你正在运行的任务,正如苹果所说,你应该让你的应用安静

  • 将用户数据保存到磁盘并关闭所有打开的文件。

  • 暂停调度和操作队列。

  • 不要安排任何新的任务来执行。

  • 使任何活动计时器无效。

  • 自动暂停游戏。

  • ...

第二步,当 UIKit 通知你的应用转移 tp 后台状态时,你必须尽快释放共享资源,如果你坚持使用这些资源,你的应用将被终止。

因此,您问题中提到的 UI 任务将被丢弃。

我还建议研究有关应用程序状态的文档,这有助于理解应用程序状态。

于 2020-05-09T06:17:31.283 回答