Skip to content

Instantly share code, notes, and snippets.

@jwilling
Last active October 26, 2020 17:02
Show Gist options
  • Star 21 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save jwilling/6012128 to your computer and use it in GitHub Desktop.
Save jwilling/6012128 to your computer and use it in GitHub Desktop.
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;
@end
#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) {
dispatch_source_cancel(source);
}
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, ^{
block();
dispatch_source_cancel(source);
[self.mappingsDictionary removeObjectForKey:identifier];
});
dispatch_resume(source);
self.mappingsDictionary[identifier] = source;
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment