【问题标题】:Is it possible to execute something on main thread after didEnterBackground is called?调用 didEnterBackground 后是否可以在主线程上执行某些操作?
【发布时间】:2020-08-24 14:49:02
【问题描述】:

首先,如果您认为我的问题很愚蠢,我想说声抱歉,我是 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 之后)或者它会在暂停之前执行用户将返回应用程序,还是将其丢弃?或者这种情况根本不可能?感谢您的帮助,如果我的问题不正确,再次抱歉。

【问题讨论】:

    标签: ios swift multithreading ios-background-mode ios-multithreading


    【解决方案1】:

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

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

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

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

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

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

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

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

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

    • 暂停调度和操作队列。

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

    • 使所有活动计时器无效。

    • 自动暂停游戏。

    • ...

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

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

    我还建议学习 this document 了解应用程序状态,这有助于理解应用程序状态。

    【讨论】:

      猜你喜欢
      • 2012-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多