22

I've been scouring Apple's documentation on application states and Grand Central Dispatch, but I haven't found a good answer to this question.

According to Apple's documentation, on iOS 4.0:

The application is in the background but is not executing code. The system moves an application to this state automatically and at appropriate times. While suspended, an application is essentially freeze-dried in its current state and does not execute any code. During low-memory conditions, the system may purge suspended applications without notice to make more space for the foreground application.

So assuming the system does not purge a suspended application (suspended -> not running transition), what happens to tasks that are currently executing in a dispatch queue? The phrase "Essentially freeze-dried" leaves much to be desired - exactly what is freeze dried?

My interpretation is whichever GCD queues an app is using at time of suspension will need to be reinstated when the app transitions back to active state; under this interpretation, the tasks existing in pre-suspension GCD queues would disappear. Is my interpretation correct?

Foo Bah
  • 25,660
  • 5
  • 55
  • 79
Rob
  • 25,984
  • 32
  • 109
  • 155

1 Answers1

24

When an app is suspended, the entire process is frozen. You can count on the process resuming as if nothing happened at all once it is resumed. Your apps's GCD logical queues don't go away, they remain as they were in memory. And the threads GCD had created in your process to service your queues are resumed in place as if nothing happened as well.

So your interpretation is incorrect: tasks existing in pre-suspension GCD queues do not disappear upon resumption. They never went away; they were only paused.

Ryan
  • 16,626
  • 2
  • 23
  • 20
  • 4
    Note: there is a reasonable chance the app will be killed while in the background. Killing the app will nuke the GCD queue, so you have to be able to re-create it on re-launch. – Kenny Winker Oct 25 '11 at 22:49
  • 7
    This is still true at least as late as iOS 9. Further, if you enqueue a block with `dispatch_after`, and the block's intended fire date passes by while the app is in the suspended state, the block will be executed immediately as soon as the app is resumed. It isn't dropped, nor will it fire N-minus-delay seconds after the app is resumed (it's an absolute date, not a relative date, that is used to calculate when the block should be executed). – jaredsinclair Oct 01 '15 at 21:19
  • @jaredsinclair are there any solutions which would allow the `dispatch_after` block to run when the app is in a suspended state? – Trent Mar 22 '20 at 03:22
  • @jaredsinclair it's very similar to RunLoop. See docs linked [here](https://stackoverflow.com/questions/605027/uiscrollview-pauses-nstimer-until-scrolling-finishes/59940345#59940345): "You can configure timers to generate events only once or repeatedly. A repeating timer reschedules itself automatically based on the scheduled firing time, not the actual firing time. For example, if a timer is scheduled to fire at a particular time and every 5 seconds after that, the scheduled firing time will always fall on the original 5 second time intervals, even if the actual firing time gets delayed.(1/2) – mfaani Feb 18 '21 at 14:10
  • If the firing time is delayed so much that it misses one or more of the scheduled firing times, the timer is fired only once for the missed time period. After firing for the missed period, the timer is rescheduled for the next scheduled firing time." (2/2) – mfaani Feb 18 '21 at 14:10