首先,如果您认为我的问题是假的,我想对不起,我是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完成下载并调用其完成,并将新任务推入主线程队列。那么在这种情况下会发生什么呢?由于didEnterBackground中的代码是在暂停之前可以执行的最后一个代码,因此downloadData的完成块会发生什么,它是否也会在暂停之前执行(在didEnterBackground之后),或者一旦用户返回到应用程序便会执行,否则将被丢弃?还是根本不可能出现这种情况?谢谢您的帮助,如果我的问题不正确,再次表示抱歉。

最佳答案

首先,我建议您考虑将此文档提供给Apple
该文档本身很清晰,但是我将仔细阅读该文档以提取与您的问题相匹配的重要信息。

苹果在本文档中明确表示,每个挂起的UI任务都将被丢弃,并且不应提交新任务到Dispatch队列,而应该挂起当前队列并尽快释放资源

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

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

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

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

    系统还需要在需要临时中断应用程序时将其停用(例如,显示系统警报)

    在这一步中,您必须暂停正在运行的任务,正如Apple所说的那样,您应该使应用安静


  • 将用户数据保存到磁盘并关闭所有打开的文件。
  • 挂起调度和操作队列。
  • 不要安排任何新任务执行。
  • 使所有 Activity 计时器无效。
  • 自动暂停游戏。
  • ...


  • 在UIKit通知您的应用有关传输tp后台状态的第二步中,您必须尽快释放共享资源,如果您继续使用这些资源,则您的应用将被终止。

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

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

    关于ios - didEnterBackground调用之后是否可以在主线程上执行某些操作?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/61689438/

    10-10 06:22