Skip to content

Instantly share code, notes, and snippets.

@yaakovgamliel
Forked from steipete/CallOncePerRunloopHelper.m
Last active August 29, 2015 14:16
Show Gist options
  • Save yaakovgamliel/d7a5059db45b2865af5a to your computer and use it in GitHub Desktop.
Save yaakovgamliel/d7a5059db45b2865af5a to your computer and use it in GitHub Desktop.
/// Performs `block` immediately and ignores subsequent calls during the same runloop.
#define pspdf_ensureCalledOnlyOncePerRunloop(block) do { \
static const char __onceKey; _pspdf_ensureCalledOnlyOncePerRunloop(self, &__onceKey, block); } while(0)
extern void _pspdf_ensureCalledOnlyOncePerRunloop(id self, const void *key, dispatch_block_t block);
void _pspdf_ensureCalledOnlyOncePerRunloop(id self, const void *key, dispatch_block_t block) {
NSCParameterAssert(block);
NSCParameterAssert(self);
PSPDFAssertOnMainThread(); // run loop needs the main thread.
BOOL hasBeenCalled = [objc_getAssociatedObject(self, key) boolValue];
if (!hasBeenCalled) {
objc_setAssociatedObject(self, key, @YES, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
block();
// clean object in the next runloop
dispatch_async(dispatch_get_main_queue(), ^{
objc_setAssociatedObject(self, key, nil, OBJC_ASSOCIATION_ASSIGN);
});
}
}
// Usage:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
[super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
pspdf_ensureCalledOnlyOncePerRunloop(^{
NSLog(@"once.");
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment