GCD延时取消

平常的开发中,经常要用到延时处理功能,一般比较实用的有2种方法,一是performSelector:withObject:afterDelay:,还有一种是GCD的dispatch_after函数,我觉得后者比前者用起来方便很多,因为是block,代码可以写在一个地方。但是dispatch_after有个缺点,就是不能取消。我们做超时处理等功能时,需要在某些条件成功以后取消这个超时的处理。而performSelectorcancelPreviousPerformRequestsWithTarget来实现取消功能。好消息是在iOS8以后多了一个GCD的取消函数。代码如下:

dispatch_block_t block = dispatch_block_create(DISPATCH_BLOCK_BARRIER, ^{
        NSLog(@"我被取消了,所以你看不到我");
    });
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(),block );
    dispatch_block_cancel(block);
// 因为有dispatch_block_cancel,所以你看不到打印。如果注释掉dispatch_block_cancel,就有打印

这里要特别说明一下,dispatch_block_t其实就是typedef void (^dispatch_block_t)(void);,它是一个普通的返回值为void,无参的block。dispatch_after的函数声明:dispatch_after(dispatch_time_t when,dispatch_queue_t queue,dispatch_block_t block);,如果要实现支持取消的dispatch_after,第三个参数你就不能传普通的dispatch_block_t,必须要传dispatch_block_createdispatch_block_create_with_qos_class
创建的block,否则不但不能取消,而且还会崩溃的。

dispatch_block_t block =  ^{
        NSLog(@"不能这样写,会崩溃的哦");
    };
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(),block );
    dispatch_block_cancel(block);

参考资料:dispatch_block_cancel

你可能感兴趣的:(GCD延时取消)