dispatch的延迟执行定时使用的时候可以传递block,使用的时候比较方便。
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, seconds * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
delay_block()
});
但没有直接的方法可以取消。
Dispatch-Cancel提供了一种方法可以取消。
typedef void(^PDDelayedBlockHandle)(BOOL cancel);
static void cancel_delayed_block(PDDelayedBlockHandle delayedHandle) {
if (nil == delayedHandle) {
return;
}
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
delayedHandle(YES);
});
}
static PDDelayedBlockHandle perform_block_after_delay(CGFloat seconds, dispatch_block_t block) {
if (block == nil) {
return nil;
}
__block dispatch_block_t blockToExecute = [block copy];
__block PDDelayedBlockHandle delayHandleCopy = nil;
PDDelayedBlockHandle delayHandle = ^(BOOL cancel) {
if (!cancel && blockToExecute) {
blockToExecute();
}
// Once the handle block is executed, canceled or not, we free blockToExecute and the handle.
// Doing this here means that if the block is canceled, we aren't holding onto retained objects for any longer than necessary.
#if !__has_feature(objc_arc)
[blockToExecute release];
[delayHandleCopy release];
#endif
blockToExecute = nil;
delayHandleCopy = nil;
};
// delayHandle also needs to be moved to the heap.
delayHandleCopy = [delayHandle copy];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, seconds * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
if (nil != delayHandleCopy) {
delayHandleCopy(NO);
}
});
return delayHandleCopy;
}
网友评论