首先,如果您认为我的问题是虚拟的,我想说声抱歉,我是 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 https://developer.apple.com/documentation/uikit/app_and_environment/scenes/preparing_your_ui_to_run_in_the_background。
该文件本身很清楚,但我将仔细阅读它以提取与您的问题相匹配的重要信息。
在本文档中,苹果明确表示每个暂停的 UI 任务都将被丢弃,并且您不应该将新任务提交到 Dispatch 队列,您应该挂起当前队列并释放资源ASAP.
当应用程序需要停用时,有两个步骤:
- 系统调用应用程序
applicationWillResignActive(_:)
方法(或sceneWillResignActive(_:)
如果您使用sceneDelegate
)
- 然后UIKit调用
applicationDidEnterBackground(_:)
方法(或sceneDidEnterBackground(_:)
)
第一步,UIKit 会通知您有关停用的信息,这意味着应用程序将在几次后进入后台。
在执行此步骤时,您必须保存所有敏感数据。
在此步骤中,如果您暂停了 UI 任务,则所有这些任务都将被丢弃。
当系统需要暂时中断应用程序时(例如,显示系统警报),系统还会停用应用程序
在此步骤中,您必须暂停正在运行的任务,正如苹果所说,您应该让您的应用程序安静
将用户数据保存到磁盘并关闭所有打开的文件。
暂停调度和操作队列。
不要安排任何新任务执行。
使任何活动的计时器无效。
自动暂停游戏。
...
在第二步中,当 UIKit 通知您的应用程序有关传输后台状态时,您必须尽快释放共享资源,如果您坚持使用这些资源,您的应用程序将被终止。
因此,您问题中提到的 UI 任务将被丢弃。
我也建议学习这个文件 https://developer.apple.com/documentation/uikit/app_and_environment/managing_your_app_s_life_cycle关于应用程序状态有助于理解应用程序状态。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)