Signals in Objective-C

Here’s the translation of the Go code to Objective-C, with explanations in Markdown format suitable for Hugo:

Objective-C provides mechanisms to handle Unix signals, allowing programs to respond intelligently to events like SIGTERM or SIGINT. Here’s how to handle signals in Objective-C using NSNotificationCenter.

#import <Foundation/Foundation.h>
#import <signal.h>

@interface SignalHandler : NSObject
@property (nonatomic, strong) dispatch_semaphore_t semaphore;
@end

@implementation SignalHandler

- (instancetype)init {
    self = [super init];
    if (self) {
        self.semaphore = dispatch_semaphore_create(0);
    }
    return self;
}

- (void)handleSignal:(int)signal {
    NSLog(@"\n%@", [NSString stringWithCString:strsignal(signal) encoding:NSUTF8StringEncoding]);
    dispatch_semaphore_signal(self.semaphore);
}

@end

void signalHandler(int sig) {
    [[NSNotificationCenter defaultCenter] postNotificationName:@"SignalReceived" object:nil userInfo:@{@"signal": @(sig)}];
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        SignalHandler *handler = [[SignalHandler alloc] init];
        
        // Register for signal notifications
        [[NSNotificationCenter defaultCenter] addObserverForName:@"SignalReceived" 
                                                          object:nil 
                                                           queue:[NSOperationQueue mainQueue] 
                                                      usingBlock:^(NSNotification *note) {
            int sig = [note.userInfo[@"signal"] intValue];
            [handler handleSignal:sig];
        }];
        
        // Set up signal handling
        signal(SIGINT, signalHandler);
        signal(SIGTERM, signalHandler);
        
        NSLog(@"awaiting signal");
        
        // Wait for a signal
        dispatch_semaphore_wait(handler.semaphore, DISPATCH_TIME_FOREVER);
        
        NSLog(@"exiting");
    }
    return 0;
}

In this Objective-C version:

  1. We create a SignalHandler class to encapsulate our signal handling logic.

  2. Instead of channels, we use NSNotificationCenter for communication between the signal handler and our main program.

  3. We use a dispatch semaphore to block the main thread until a signal is received, similar to the channel in the original example.

  4. The signalHandler function is set up to handle the actual signals and post notifications.

  5. In the main function, we set up an observer for signal notifications and wait on the semaphore.

To run this program:

  1. Save the code in a file named SignalHandler.m.
  2. Compile it using:
    $ clang -framework Foundation SignalHandler.m -o SignalHandler
  3. Run the compiled program:
    $ ./SignalHandler
    awaiting signal

When we run this program, it will block waiting for a signal. By typing ctrl-C (which the terminal shows as ^C), we can send a SIGINT signal, causing the program to print the signal name and then exit.

$ ./SignalHandler
awaiting signal
^C
Interrupt: 2
exiting

This example demonstrates how to handle signals in Objective-C, providing a way for programs to respond gracefully to external events or interrupts.