The concurrency tools on iOS and Mac are numerous and the decision about which technology to employ often comes down to the level of abstraction that the developer wants to use. For many concurrency problems, NSOperation
and NSOperationQueue
is sufficient.
One nearly intractable problem that I face in several applications is the need to wait on multiple web service calls to complete before starting another process. I use AFNetworking almost exclusively in my applications because it simplifies asynchronous web service work. In this case, dispatch groups and NSOperationQueue
don’t work, because we only know when the job has been submitted, not when it has been completed. We need to be able to wait on multiple already-asynchronous tasks to complete. In this post, I’ll describe how I go about solving the problem.
Let’s say I have an object Foo
that needs to be registered with my web service. Foo
has a category that handles the registration process and executes a completion block. The solution I’m describing uses dispatch_group_enter
and dispatch_group_leave
along with waiting on a background queue. In this scenario, I must wait for the group to complete on a background queue because I’m firing off the asynchronous web services calls on the main queue. If I wait on the same main queue, than I block its execution and I’m deadlocked. So, my dispatch_group_wait
is on a background queue.
1 | for( Foo *foo in pendingRegistrations ) { |