Channels in Objective-C

In Objective-C, we can use Grand Central Dispatch (GCD) to achieve similar functionality to Go’s channels. GCD provides a way to manage concurrent operations and communicate between different parts of your code.

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // Create a dispatch queue for concurrent operations
        dispatch_queue_t queue = dispatch_queue_create("com.example.queue", DISPATCH_QUEUE_CONCURRENT);
        
        // Create a dispatch semaphore to synchronize operations
        dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
        
        // Create an NSString to hold our message
        __block NSString *message;
        
        // Dispatch an asynchronous task to send a message
        dispatch_async(queue, ^{
            message = @"ping";
            dispatch_semaphore_signal(semaphore);
        });
        
        // Wait for the message to be sent
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        
        // Print the received message
        NSLog(@"%@", message);
    }
    return 0;
}

In this Objective-C example:

  1. We create a concurrent dispatch queue using dispatch_queue_create. This is similar to creating a channel in Go.

  2. We use a dispatch semaphore (dispatch_semaphore_t) to synchronize operations between the sending and receiving of the message. This helps us achieve similar behavior to Go’s channel send and receive operations.

  3. We declare a __block NSString *message to hold our message. The __block specifier allows the variable to be modified within the block.

  4. We dispatch an asynchronous task using dispatch_async. This is similar to launching a goroutine in Go. Inside this task, we set the message and signal the semaphore.

  5. We use dispatch_semaphore_wait to wait for the message to be sent. This is similar to receiving from a channel in Go.

  6. Finally, we print the received message using NSLog.

When we run the program, the “ping” message is successfully passed from one asynchronous task to the main thread via our dispatch queue and semaphore.

$ gcc -framework Foundation channels.m -o channels
$ ./channels
2023-06-01 12:34:56.789 channels[12345:67890] ping

By default, the dispatch semaphore allows us to synchronize the sending and receiving of the message, similar to how channel sends and receives block in Go until both the sender and receiver are ready. This property allowed us to wait at the end of our program for the “ping” message without having to use any other synchronization mechanism.