Skip to content

Instantly share code, notes, and snippets.

@jeffaburt
Created April 18, 2016 14:30
Show Gist options
  • Save jeffaburt/2144270416bd148901271ef7f60656a4 to your computer and use it in GitHub Desktop.
Save jeffaburt/2144270416bd148901271ef7f60656a4 to your computer and use it in GitHub Desktop.
dispatch_after with the ability to cancel execution
//
// DispatchAfterWithCancel.h
//
// Created by Jeff Burt on 4/18/16.
// Copyright © 2016 Jeff Burt. All rights reserved.
//
#ifndef DispatchAfterWithCancel_h
#define DispatchAfterWithCancel_h
typedef void(^dispatch_after_with_cancel_t)(BOOL shouldCancel);
/**
* Provides a dispatch_after block that can be canceled before its execution.
* The block will be called on the main thread.
*
* To cancel the block before it executes, simply call `cancel_block` with
* the block returned by this function.
*
* This function will always return a non-null `dispatch_after_with_cancel_t`
* block, even if the `block` provided is NULL.
*
* @param delay the time to wait before execution
* @param block the block to execute
*
* @return a block that will execute after the set delay. Calling `cancel_block`
* with this block will cancel the block before it executes.
*/
NS_INLINE dispatch_after_with_cancel_t dispatch_after_with_cancel(NSTimeInterval delay, dispatch_block_t block) {
__block dispatch_block_t originalBlock = [block copy];
__block dispatch_after_with_cancel_t cancelableBlock = ^(BOOL shouldCancel) {
if (shouldCancel == NO && originalBlock) {
originalBlock();
}
originalBlock = NULL;
};
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, delay * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
if (cancelableBlock) {
cancelableBlock(NO);
cancelableBlock = NULL;
}
});
return cancelableBlock;
}
/**
* Cancels the block before it executes. Does nothing when a NULL block is
* provided.
*
* @param block the block to cancel
*/
NS_INLINE void cancel_block(dispatch_after_with_cancel_t block) {
if (block) {
block(YES);
block = NULL;
}
}
#endif
//
// ViewController.m
//
// Created by Jeffrey Burt on 4/18/16.
// Copyright © 2016 Jeff Burt. All rights reserved.
//
#import "ViewController.h"
#import "DispatchAfterWithCancel.h"
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
dispatch_after_with_cancel_t block = dispatch_after_with_cancel(3, ^{
NSLog(@"Hello world!");
});
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"Canceling block early");
cancel_block(block);
});
}
@end
@dautermann
Copy link

Looks like somebody is psyching up for an upcoming Facebook interview and a potential move to the Left Coast. The original Glassdoor article (and question) you're responding to is mine. 😜 Best of luck to you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment