Waitgroups in Objective-C
Our first example demonstrates the use of a dispatch group, which is similar to a wait group. It allows us to wait for multiple asynchronous tasks to finish.
#import <Foundation/Foundation.h>
// This is the function we'll run in every dispatch queue.
void worker(int id) {
NSLog(@"Worker %d starting", id);
// Sleep to simulate an expensive task.
[NSThread sleepForTimeInterval:1.0];
NSLog(@"Worker %d done", id);
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
// This dispatch group is used to wait for all the
// dispatch queues launched here to finish.
dispatch_group_t group = dispatch_group_create();
// Launch several dispatch queues and add them to the dispatch group.
for (int i = 1; i <= 5; i++) {
dispatch_group_enter(group);
// Wrap the worker call in a block that makes sure to tell
// the dispatch group that this worker is done. This way the worker
// itself does not have to be aware of the concurrency primitives
// involved in its execution.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
worker(i);
dispatch_group_leave(group);
});
}
// Block until all tasks in the dispatch group are done.
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
// Note that this approach has no straightforward way
// to propagate errors from workers. For more
// advanced use cases, consider using NSOperation and NSOperationQueue.
}
return 0;
}
To run the program, compile it and then execute:
$ clang -framework Foundation waitgroups.m -o waitgroups
$ ./waitgroups
Worker 3 starting
Worker 1 starting
Worker 2 starting
Worker 4 starting
Worker 5 starting
Worker 3 done
Worker 1 done
Worker 2 done
Worker 4 done
Worker 5 done
The order of workers starting up and finishing is likely to be different for each invocation.
In this Objective-C version, we use Grand Central Dispatch (GCD) which is the native concurrency framework for iOS and macOS. The dispatch_group_t
is analogous to the WaitGroup
in Go. We use dispatch_group_enter
and dispatch_group_leave
to increment and decrement the group’s counter, respectively. The dispatch_group_wait
function blocks until all tasks in the group are complete, similar to WaitGroup.Wait()
in Go.
Note that Objective-C and the iOS/macOS ecosystem don’t have a direct equivalent to goroutines. Instead, we use GCD’s dispatch queues to perform concurrent operations. This approach provides similar functionality but with a different API and underlying implementation.