Is it possible to execute something on main thread after didEnterBackground is called?

女生的网名这么多〃 提交于 2020-08-09 19:34:08

问题


First of all I'd like to say sorry in case you consider my question dummy, I'm new to iOS and multithreading and just want to understand how things are going on. As far as I know didEnterBackground is the last function that iOS calls before app suspension and the app has about 5 secs to return from it otherwise iOS will kill the app. I'm currently thinking about such a situation - I have some task that is happening on the background thread(e.g. network download) and its completion block happens on the main thread. like this

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() is currently running on the background thread, the user taps on the home button and the app goes to background and didEnterBackground is called. While main thread executes code in didEnterBackground downloadData finishes downloading and its completion is called and the new task is pushed into main threads queue. So what would happen in this case? Since the code from didEnterBackground is the last that can be execute before the suspension what would happen to the completion block of downloadData, would it also be executed before the suspension(after didEnterBackground) or it would be executed once the user will return to the app, or it will be discarded? Or this situation is not possible at all ? Thank you for your help and again sorry if my question is incorrect.


回答1:


First of all, I suggest you consider this document provided Apple. The document is clear by itself, but I'll go through it to extract important information that matches your question.

In this document, apple says explicitly that every suspended UI task will be discarded and you should not submit new tasks to Dispatch queues and you should suspend the current queues and release resources ASAP.

When app is supposed to be deactivated, There are two steps:

  1. System calls application applicationWillResignActive(_:) method (or sceneWillResignActive(_:) If your using sceneDelegate)
  2. Then UIKit calls applicationDidEnterBackground(_:) method (or sceneDidEnterBackground(_:))

In the first step, UIKit is notifying you about deactivation, which implies that after a few times later, the app will enter in background. While this step, you must save all the sensitive data.

During this step, if you have suspended UI tasks, All of them will be discarded.

The system also deactivates apps when it needs to interrupt them temporarily—for example, to display system alerts

During this step, you must pause your running task, As Apple says, You should make your app quiet

  • Save user data to disk and close any open files.

  • Suspend dispatch and operation queues.

  • Don’t schedule any new tasks for execution.

  • Invalidate any active timers.

  • Pause gameplay automatically.

  • ...

In the Second steps when UIKit notifies your app about transferring tp background state, You must free shared resources as quickly as possible, If you persist to use the resources your app will be terminated.

So the mentioned UI task in your question will be discarded.

I also recommend studying this document about app states which helps with understanding application state.



来源:https://stackoverflow.com/questions/61689438/is-it-possible-to-execute-something-on-main-thread-after-didenterbackground-is-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!