1

My DispatchQueue task needs to be on global queue with QOS .user-initiated.

Task is an endless loop and at end of each loop needs to sleep for 1 second, allowing other threads to run.

And, once per loop, task also dispatches a task onto main queue to update display.

Doug Null
  • 7,989
  • 15
  • 69
  • 148
  • 1
    This is rather contradictory. You said you want it to run on the main queue with QOS user initiated, but the main queue has the higher QOS of user interactive... But anyway, it sounds like you should be running this on a `global` system queue, or your own queue. – Sweeper Apr 23 '21 at 00:27
  • 1
    You still seem to be thinking in terms of threads. With dispatch queues, you don't need to "sleep the queue" (makes no sense) to allow other tasks to run. The QOS of the queue decides how important that queue's tasks are, and more important tasks are run more frequently, less important tasks are put on hold more frequently. If you haven't already, [read this](https://developer.apple.com/library/archive/documentation/General/Conceptual/ConcurrencyProgrammingGuide/ThreadMigration/ThreadMigration.html). – Sweeper Apr 23 '21 at 00:36
  • Very sorry, Sweeper; quite right; I neglected 2nd task. 1st task on global queue is exec loop that does two things: [A] puts a 2nd task onto main task to update UI and die; and [B] delays 1 second. – Doug Null Apr 23 '21 at 00:40
  • Sweeper: essentially I want a loop that updates a UIImageView and then not update it again for 1 second. What's the GCD way? – Doug Null Apr 23 '21 at 00:41
  • 2
    With *very few* exceptions, you never want to sleep a thread in your app. What you're really looking for is a way to periodically enqueue work. That's what `DispatchSourceTimer` and `Foundation.Timer` are for. See https://stackoverflow.com/a/55329816/3141234 for a comparison. Nowadays, I would probably do this using a Combine Timer publisher. – Alexander Apr 23 '21 at 00:45
  • 2
    You might just be thinking of an ordinary repeating Timer. If you really want a GCD version, that exists too, but it could be overkill for your use case. – matt Apr 23 '21 at 00:50
  • What's the problem with sleeping a thread, if it's on the global queue? When it sleeps, everything of higher priority runs, right? And it doesn't do anything while sleeping -- through the O.S. multitasking I assume periodically checks the sleep time. Coding a single line sleep(n) is a lot faster than coding all the overhead of full blown timer usage, I would think. Code sleep() -- 15". Code periodic enqueuing -- 30' at least. Life's too short. – Doug Null Apr 23 '21 at 16:24

1 Answers1

0

This worked great: DispatchQueue.global().sync() { sleep(1) }

..and, yes, took only 15" to code.

Doug Null
  • 7,989
  • 15
  • 69
  • 148
  • 1
    This blocks a whole thread to just wait, which is incredibly costly. Threads are a finite resource in iOS. You want a timer here or an `asyncAfter`. (Ah, I see this was mentioned several times in the comments above as well. Sweeper, Alexander, and matt are right. This is an incredibly inefficient way insert a delay.) – Rob Napier Apr 23 '21 at 19:51