Skip to content

Instantly share code, notes, and snippets.

Last active October 26, 2020 17:02
What would you like to do?
Simple throttling of blocks using dispatch sources.
#import <Foundation/Foundation.h>
@interface JNWThrottledBlock : NSObject
// Runs the block after the buffer time _only_ if another call with the same identifier is not received
// within the buffer time. If a new call is received within that time period the buffer will be reset.
// The block will be run on the main queue.
// Identifier and block must not be nil.
+ (void)runBlock:(void (^)())block withIdentifier:(NSString *)identifier throttle:(CFTimeInterval)bufferTime;
#import "JNWThrottledBlock.h"
@implementation JNWThrottledBlock
+ (NSMutableDictionary *)mappingsDictionary {
static NSMutableDictionary *mappings = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
mappings = [NSMutableDictionary dictionary];
return mappings;
+ (void)runBlock:(void (^)())block withIdentifier:(NSString *)identifier throttle:(CFTimeInterval)bufferTime {
if (block == NULL || identifier == nil) {
NSAssert(NO, @"block or identifier must not be nil");
dispatch_source_t source = self.mappingsDictionary[identifier];
if (source != nil) {
source = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
dispatch_source_set_timer(source, dispatch_time(DISPATCH_TIME_NOW, bufferTime * NSEC_PER_SEC), DISPATCH_TIME_FOREVER, 0);
dispatch_source_set_event_handler(source, ^{
[self.mappingsDictionary removeObjectForKey:identifier];
self.mappingsDictionary[identifier] = source;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment