Title here
Summary here
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:
dispatch_semaphore_t
is used to signal when an operation is complete, similar to channels in the original example.dispatch_semaphore_wait
with a timeout is used to implement the timeout functionality, replacing the select
statement with time.After
.NSLog
is used for printing output instead of fmt.Println
.@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.