Skip to content

Instantly share code, notes, and snippets.

@sgl0v
Forked from zwaldowski/NSObject+Blocks.h
Created March 14, 2013 19:40
Show Gist options
  • Save sgl0v/5164498 to your computer and use it in GitHub Desktop.
Save sgl0v/5164498 to your computer and use it in GitHub Desktop.
Cancellable blocks
//
// NSObject+Blocks.h
// Filemator
//
// Created by Zachary Waldowski on 4/12/11.
// Copyright 2011 Dizzy Technology. All rights reserved.
//
@interface NSObject (Blocks)
+ (id)performBlock:(void (^)(void))block afterDelay:(NSTimeInterval)delay;
+ (id)performBlock:(void (^)(id arg))block withObject:(id)anObject afterDelay:(NSTimeInterval)delay;
- (id)performBlock:(void (^)(void))block afterDelay:(NSTimeInterval)delay;
- (id)performBlock:(void (^)(id arg))block withObject:(id)anObject afterDelay:(NSTimeInterval)delay;
+ (void)cancelBlock:(id)block;
@end
//
// NSObject+Blocks.m
// Filemator
//
// Created by Zachary Waldowski on 4/12/11.
// Copyright 2011 Dizzy Technology. All rights reserved.
//
#import "NSObject+Blocks.h"
#import <dispatch/dispatch.h>
static inline dispatch_time_t dTimeDelay(NSTimeInterval time) {
int64_t delta = (int64_t)(NSEC_PER_SEC * time);
return dispatch_time(DISPATCH_TIME_NOW, delta);
}
@implementation NSObject (Blocks)
+ (id)performBlock:(void (^)(void))block afterDelay:(NSTimeInterval)delay {
if (!block) return nil;
__block BOOL cancelled = NO;
void (^wrappingBlock)(BOOL) = ^(BOOL cancel) {
if (cancel) {
cancelled = YES;
return;
}
if (!cancelled)block();
};
wrappingBlock = [[wrappingBlock copy] autorelease];
dispatch_after(dTimeDelay(delay), dispatch_get_main_queue(), ^{ wrappingBlock(NO); });
return wrappingBlock;
}
+ (id)performBlock:(void (^)(id arg))block withObject:(id)anObject afterDelay:(NSTimeInterval)delay {
if (!block) return nil;
__block BOOL cancelled = NO;
void (^wrappingBlock)(BOOL, id) = ^(BOOL cancel, id arg) {
if (cancel) {
cancelled = YES;
return;
}
if (!cancelled) block(arg);
};
wrappingBlock = [[wrappingBlock copy] autorelease];
dispatch_after(dTimeDelay(delay), dispatch_get_main_queue(), ^{ wrappingBlock(NO, anObject); });
return wrappingBlock;
}
- (id)performBlock:(void (^)(void))block afterDelay:(NSTimeInterval)delay {
if (!block) return nil;
__block BOOL cancelled = NO;
void (^wrappingBlock)(BOOL) = ^(BOOL cancel) {
if (cancel) {
cancelled = YES;
return;
}
if (!cancelled) block();
};
wrappingBlock = [[wrappingBlock copy] autorelease];
dispatch_after(dTimeDelay(delay), dispatch_get_main_queue(), ^{ wrappingBlock(NO); });
return wrappingBlock;
}
- (id)performBlock:(void (^)(id arg))block withObject:(id)anObject afterDelay:(NSTimeInterval)delay {
if (!block) return nil;
__block BOOL cancelled = NO;
void (^wrappingBlock)(BOOL, id) = ^(BOOL cancel, id arg) {
if (cancel) {
cancelled = YES;
return;
}
if (!cancelled) block(arg);
};
wrappingBlock = [[wrappingBlock copy] autorelease];
dispatch_after(dTimeDelay(delay), dispatch_get_main_queue(), ^{ wrappingBlock(NO, anObject); });
return wrappingBlock;
}
+ (void) cancelBlock:(id)block {
if (!block) return;
void (^aWrappingBlock)(BOOL) = (void(^)(BOOL))block;
aWrappingBlock(YES);
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment