Channel Synchronization in Objective-C
Our example demonstrates how to synchronize execution across different threads. We’ll use a block to notify the main thread when a background operation is complete. This is similar to using dispatch groups or semaphores in Objective-C.
#import <Foundation/Foundation.h>
// This is the function we'll run in a background thread. The
// completion handler will be used to notify the main thread
// that this function's work is done.
void worker(void (^completion)(void)) {
NSLog(@"working...");
[NSThread sleepForTimeInterval:1.0];
NSLog(@"done");
// Call the completion handler to notify that we're done.
completion();
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
// Create a dispatch group to wait for the background work
dispatch_group_t group = dispatch_group_create();
// Start a worker in a background thread, giving it the group to notify on
dispatch_group_enter(group);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
worker(^{
dispatch_group_leave(group);
});
});
// Block until we receive a notification from the worker on the group
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
return 0;
}
}
To run the program, compile it and then execute:
$ clang -framework Foundation channel-synchronization.m -o channel-synchronization
$ ./channel-synchronization
working...
done
If you removed the dispatch_group_wait
line from this program, the program would exit before the worker
even started.
In this Objective-C version, we use Grand Central Dispatch (GCD) to manage concurrency. The dispatch_group_t
serves a similar purpose to the channel in the original example, allowing us to wait for the background work to complete before the program exits.
The worker
function now takes a completion handler block instead of a channel. This block is called when the work is done, similar to sending a value on a channel.
In the main
function, we create a dispatch group, start the worker on a background queue, and then wait for it to complete using dispatch_group_wait
. This achieves the same synchronization as the original example, but in a more Objective-C idiomatic way.