GCD的延时操作
我们经常在使用CGD延时之后,一般无法取消,苹果没有提供相对应的api接口,我们通过对GCD的封装来取消延时。
下面我们直接上代码:
typedef void(^SMDelayedBlockHandle)(BOOL cancel);
static SMDelayedBlockHandle perform_block_after_delay(CGFloat seconds, dispatch_block_t block) {
if (nil == block) {
return nil;
}
__block dispatch_block_t blockToExecute = [block copy];
__block SMDelayedBlockHandle delayHandleCopy = nil;
//我们新建一个block回调,当延迟操作完成时,让GCD走这个回调,我们可以控制这个回调的取消。
SMDelayedBlockHandle delayHandle = ^(BOOL cancel){
if (NO == cancel && nil != blockToExecute) {
dispatch_async(dispatch_get_main_queue(), blockToExecute);
}
blockToExecute = nil;
delayHandleCopy = nil;
};
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;
};
//我们使用perform_block_after_delay方法进行延迟处理,_delayedBlockHandle负责控制取消延迟的操作
__block SMDelayedBlockHandle blockHandle = _delayedBlockHandle;
_delayedBlockHandle = perform_block_after_delay(2.0f, ^{
blockHandle = nil;
});
//我们使用这个方法就可以取消perform_block_after_delay放发回调
_delayedBlockHandle(YES);