Timeouts in Objective-C

Timeouts are important for programs that connect to external resources or that otherwise need to bound execution time. Implementing timeouts in Objective-C is possible using Grand Central Dispatch (GCD) and blocks.

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        
        // For our example, suppose we're executing an external
        // call that returns its result on a dispatch_semaphore_t after 2s.
        dispatch_semaphore_t semaphore1 = dispatch_semaphore_create(0);
        dispatch_async(queue, ^{
            [NSThread sleepForTimeInterval:2.0];
            NSLog(@"result 1");
            dispatch_semaphore_signal(semaphore1);
        });
        
        // Here's the implementation of a timeout.
        // We'll use dispatch_semaphore_wait with a timeout to achieve this.
        dispatch_time_t timeout1 = dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC);
        if (dispatch_semaphore_wait(semaphore1, timeout1) == 0) {
            NSLog(@"Received result 1");
        } else {
            NSLog(@"timeout 1");
        }
        
        // If we allow a longer timeout of 3s, then the wait
        // for semaphore2 will succeed and we'll print the result.
        dispatch_semaphore_t semaphore2 = dispatch_semaphore_create(0);
        dispatch_async(queue, ^{
            [NSThread sleepForTimeInterval:2.0];
            NSLog(@"result 2");
            dispatch_semaphore_signal(semaphore2);
        });
        
        dispatch_time_t timeout2 = dispatch_time(DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC);
        if (dispatch_semaphore_wait(semaphore2, timeout2) == 0) {
            NSLog(@"Received result 2");
        } else {
            NSLog(@"timeout 2");
        }
    }
    return 0;
}

Running this program shows the first operation timing out and the second succeeding.

$ clang main.m -framework Foundation -o timeouts && ./timeouts
timeout 1
result 1
result 2
Received result 2

In this Objective-C version:

  1. We use Grand Central Dispatch (GCD) for concurrency instead of goroutines.
  2. dispatch_semaphore_t is used to signal when an operation is complete, similar to channels in the original example.
  3. dispatch_semaphore_wait with a timeout is used to implement the timeout functionality, replacing the select statement with time.After.
  4. NSLog is used for printing output instead of fmt.Println.
  5. The @autoreleasepool block is used to manage memory automatically.

While the structure is different due to language differences, the core concept of implementing timeouts remains the same.

查看推荐产品

Comments powered by Disqus