3

I've been trying to move away from targeting specific threads and thinking more about queues like suggested by best practices and guidelines in the iOS arena.

WHAT I USED TO DO: I used to be able to create a new thread, then run a runloop on it. Every time I wanted a task to be run on that thread I would call performselector:onThread:. That gave me a way to target a specific thread and more importantly to know that the work was going to to be associated with the NSRunLoop I started.

WHAT I'VE SEEN PEOPLE DO NOW WITH QUEUES AND NSRUNLOOPs: I saw this post on stack overflow: iOS, NSURLConnection: Delegate Callbacks on Different Thread?

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSRunLoop *loop = [NSRunLoop currentRunLoop];
    [connection scheduleInRunLoop:loop forMode:NSRunLoopCommonModes];
    [loop run]; // make sure that you have a running run-loop.
});

I don't see how this could address what I used to do with threads. Why? This is what I'm thinking and I would like to know if what I'm thinking is right or to see if I'm missing some major conceptual point that makes me think that this does not allow me to do with queues what I used to do with threads.

  1. In my understanding GCD manages threads for the user. So, by calling:

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),.... I am not actually able to know what thread is actually associated with the NSRUNLOOP that is started in the block here above. So, if I am thinking this right, GCD picks a thread when I go on a queue, so then how can I leverage the same runloop I started the last time I was put on the global queue by GCD?

I used to have a static variable for a specific thread, who then had an entry point to the NSRUNLOOP. Now, that I only want to deal with queues, how could I say "go on thread A, do a bunch of work" knowing that that thread a specific runloop I started?

So, I am assuming that the approach of doing:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSRunLoop *loop = [NSRunLoop currentRunLoop];
    [connection scheduleInRunLoop:loop forMode:NSRunLoopCommonModes];
    [loop run]; // make sure that you have a running run-loop.
});

would create a new runloop every time I do that. Instead, I want to be able to have only one runloop I do work on.

Can anybody tell me how to get work done on a specific runloop (other than the one used by the main thread) using queues instead of NSThreads, and clarify this whole discussion I made up here?

Thank you

Community
  • 1
  • 1
zumzum
  • 17,984
  • 26
  • 111
  • 172
  • 1
    Just one point of clarification - you can't create runloops. Each thread has a runloop and `[NSRunLoop currentRunLoop]` retrieves that runloop. It doesn't create a new one – Paulw11 Jul 07 '14 at 21:29
  • The concurrency programming guide https://developer.apple.com/library/ios/documentation/general/conceptual/concurrencyprogrammingguide/ThreadMigration/ThreadMigration.html#//apple_ref/doc/uid/TP40008091-CH105-SW1 has a section on migrating away from threads. You can use serial or concurrent queues to replace specific worker threads or a concurrent queue to replace thread pools – Paulw11 Jul 07 '14 at 21:36
  • ok, so, what I am trying to stay away from is to do something like this [NSRunLoop currentRunLoop] on a bunch of not so busy threads when I just used to divert all the work to the same thread before using queues. I had a reference to my thread and all work would always go on that specific thread who had a runloop that would keep him alive even when not busy – zumzum Jul 07 '14 at 21:44
  • If the methods can execute in any order then just dispatch them on a concurrent queue of the appropriate priority and let GCD work it out. If you need a specific order then dispatch them in a serial queue. Aside from the main thread with GCD you probably don't need to know about any specific thread – Paulw11 Jul 07 '14 at 21:48
  • Here's what apple says: "It is important to remember that queues are not a panacea for replacing threads. The asynchronous programming model offered by queues is appropriate in situations where latency is not an issue. Even though queues offer ways to configure the execution priority of tasks in the queue, higher execution priorities do not guarantee the execution of tasks at specific times. Therefore, threads are still a more appropriate choice in cases where you need minimal latency". So, if they recognize that Threads might still be a need, then how do I send a task on a specific thread? – zumzum Jul 07 '14 at 22:26
  • That is true. If you need low latency then there is nothing wrong with what you are doing. If you just need concurrency and latency isn't critical then GCD is typically simpler. In other words, if you need threads, use threads not queues. – Paulw11 Jul 07 '14 at 22:28

0 Answers0