3

So when using dispatch_async ...

Say you're making a network connection for example...

dispatch_queue_t otherQ = dispatch_queue_create(NULL, 0);

__weak MyClass *myself = self;
dispatch_async(otherQ,
    ^{
     myself.searchResultsRA = [myself dataFrom:happyUrl ifError:nil];
    dispatch_async(dispatch_get_main_queue(), ^{ if (after) after(); });
    });

dispatch_release(otherQ);

Notice I am creating a queue "right there" for that call.

So, every call like that in the app, simply creates its own queue "there and then" to use.

Alternately, you can just create one queue as a global for your app, and keep it around, and always use that one same queue. (I guess, you'd really "never release it" it would just persist for the life of the app.)

(Note - I am not talking about Apple's "global queue" ..dispatch_get_global_queue .. nothing to do with that .. I simply mean you can create your own one queue and always use that same queue.)

I've never really understood if one approach is preferred or if there are dangers associated with either, or any other issues.

In short, which approach to use?

Fattie
  • 27,874
  • 70
  • 431
  • 719

2 Answers2

3

These alternatives accomplish very different things. If you create a new queue each time, then all of them can run at once. If you always use the same (serial; doesn't apply to concurrent ones) queue, the blocks on it will run one at a time in order.

You would typically use the latter in either of two situations:

  • To protect something that's not threadsafe from being used from more than one thread at once (most common use of serial queues)

  • To intentionally reduce the amount of concurrency in your app to conserve resources (whether that be memory, or server connections, or what).

Catfish_Man
  • 41,261
  • 11
  • 67
  • 84
  • Excellent, thanks! Gotta think about that :) Just one question, something you touched on: if you ARE using (your OWN) concurrent queue. In fact: is it utterly pointless ever making more than one? TBC, there's no advantage / difference / disadvantage at all, to making more than one of your own concurrent queue versus just using one of your own concurrent queue? (In this comment I am purely asking about the side issue of concurrent queues!!) thanks!! – Fattie Sep 29 '14 at 06:42
  • There's one major case it's important: dispatch_barrier_async(). Other than that there's a few tricky areas where it's useful (queue priorities, re targeting queues, suspending queues, etc...), but for the general "just do some threadsafe work for me" case, you may as well just use a global queue and not bother making one of your own at all. – Catfish_Man Sep 29 '14 at 06:48
1

In addition to the answer from @Catfish_Man, consider that you currently have no control over how many downloads you're running concurrently and that you have no ability to cancel the downloads if the user changes their mind. Do you really want to make the user wait for one thing before requesting another, or risk flooding the network with requests and having them all fail?

In general, should you really be using GCD, or should you really opt for the higher level NSOperationQueue APIs.

Ising GCD directly, while it may offer the 'minimum code to write', does come with drawbacks/compromises and you should make yourself aware of them before using that approach.

Wain
  • 118,658
  • 15
  • 128
  • 151
  • HI Wain - all quite true. (Also note this other Q of mine - which Catfish also A'd!! :) http://stackoverflow.com/q/25014581/294884 ) Here I was more just trying to clarify what the hell is going on when (if you are using dispatch_async) you use "new queue every time" versus "your own one queue"... – Fattie Sep 29 '14 at 06:50