0

For my ios app I am using the main queue and root queue. I have several objects and I want their mehtods to run in the root queue. So far, what I have been doing is add a dispatch_async for each time I call one of those methods which will ultimately become very troublesome when I will use more queues and want to go back to main queue. What I am looking for is way to assign objects to the root queue so that their methods are executed in the roof queue. What I mean is I am looking for sth. like this: [[TestClass alloc] initInQueue:testQueue];

Woodstock
  • 22,184
  • 15
  • 80
  • 118

1 Answers1

0

It is possible to create this in a manner similar to KVO. You could swizzle all your methods to wrap them into dispatch_* calls, but I would strongly discourage it. The level of magic is too high, and you will almost certainly tie yourself up in knots. Moreover, you can't wrap an arbitrary method in dispatch_async since you can't have a return result from that. But you also can't wrap arbitrary methods in dispatch_sync because you would likely deadlock. The problems of solving the general case will quickly spiral out of control in my opinion.

What you should be asking instead is whether your queue architecture is correct. Do you really need to keep calling so many small methods on other queues? In many cases it is better to encapsulate full work units (i.e. a coherent sequence of operations that take an input and generate a final result) rather than individual method calls. (Once you think in work units, NSOperation suddenly gets a lot more useful.) While it is occasionally useful to wrap an accessor into a queue for thread-safety, this is not a general solution to concurrency.

While there are advantages to getting off of the main queue, this advice shouldn't be over-applied. You can do reasonable amounts of work on the main queue without any problems. We built single-threaded Cocoa apps on computers less powerful than iPhones long before GCD. (The iPhone is probably more powerful than my old PowerBooks and might be more powerful than my original MacBook.) I'm not discouraging queues here, just make sure you're doing it for the right reasons and don't overcomplicate things.

But if you really need to move the work, then I would recommend just being explicit with dispatch_ calls in the method itself. It's a little more typing, but it's much clearer and less error-prone.

Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • Thank your for your answer. I really liked it. – user3057326 Jun 02 '14 at 13:15
  • The thing is I am using a delegate that is managed by ios and has to run in another queue than the main queue (CBCentralManager delegate). And from there on it just spreads all over to the other methods. My general idea is to have most of the 'model' part to be executed in the queue where the delegate is running in and use the main queue for the gui parts. – user3057326 Jun 02 '14 at 13:24
  • I don't understand what you mean by "has to run in another queue than the main queue." `CBCentralManager` will dispatch to any queue you request (`initWithDelegate:queue:`). If you pass `nil`, it'll dispatch to the main queue. – Rob Napier Jun 02 '14 at 13:38
  • dispatchment to the mainqueue does not happen as others have reported here for instance: http://stackoverflow.com/questions/22412376/corebluetooth-state-preservation-issue-willrestorestate-not-called-in-ios-7-1 – user3057326 Jun 02 '14 at 15:17