Tickers in Objective-C
Timers are for when you want to do something once in the future - tickers are for when you want to do something repeatedly at regular intervals. Here’s an example of a ticker that ticks periodically until we stop it.
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
// Tickers use a similar mechanism to timers: a dispatch source that fires at regular intervals.
// Here we'll use a dispatch source to create events every 500ms.
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
dispatch_source_set_timer(timer, dispatch_walltime(NULL, 0), 500 * NSEC_PER_MSEC, 100 * NSEC_PER_MSEC);
__block BOOL shouldStop = NO;
dispatch_source_set_event_handler(timer, ^{
if (shouldStop) {
dispatch_source_cancel(timer);
return;
}
NSDate *currentTime = [NSDate date];
NSLog(@"Tick at %@", currentTime);
});
dispatch_resume(timer);
// We'll stop our ticker after 1600ms.
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1600 * NSEC_PER_MSEC), dispatch_get_main_queue(), ^{
shouldStop = YES;
NSLog(@"Ticker stopped");
});
// Keep the main thread alive
[[NSRunLoop currentRunLoop] run];
}
return 0;
}
When we run this program the ticker should tick 3 times before we stop it.
$ gcc -framework Foundation ticker.m -o ticker
$ ./ticker
2023-06-08 15:30:00.123 ticker[12345:67890] Tick at 2023-06-08 15:30:00 +0000
2023-06-08 15:30:00.623 ticker[12345:67890] Tick at 2023-06-08 15:30:00 +0000
2023-06-08 15:30:01.123 ticker[12345:67890] Tick at 2023-06-08 15:30:01 +0000
2023-06-08 15:30:01.623 ticker[12345:67890] Ticker stopped
In this Objective-C version, we use Grand Central Dispatch (GCD) to create a timer that fires every 500 milliseconds. The dispatch_source_t
is similar to a ticker in that it repeatedly performs an action at regular intervals. We use a block to handle each tick event, printing the current time.
Instead of using channels like in the original example, we use a boolean flag shouldStop
to control when the ticker should stop. After 1600 milliseconds, we set this flag to YES
, which causes the ticker to stop on its next iteration.
Note that Objective-C and the iOS/macOS frameworks don’t have a direct equivalent to Go’s ticker, but the combination of GCD’s timer source and dispatch queues provides similar functionality.