这段时间有个swift项目,需要用到延时执行,并且中途有可能取消执行的功能,想起喵神在100个tips的书里有篇文章说到过这个功能,用GCD实现的,于是找到这篇文章把源码照搬了过来,发现在swfit4下GCD的语法改变还是挺多的,之前的写法很多都编译不过去,出于abi还没稳定,可能将来还有变化的考虑,就先不做详细研究了,先简单按照错误提示把他改成能用的就成,如果有需要的朋友就直接拿去吧,这里再次感谢作者喵神

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
typealias Task = (_ cancel : Bool) -> Void
func delay(time:TimeInterval, task:@escaping ()->()) -> Task? {
let delay = DispatchTime.now() + time;
func dispatch_later(block:@escaping ()->()) {
DispatchQueue.main.asyncAfter(deadline: delay, execute: block);
}
var closure: (()->())? = task
var result: Task?
let delayedClosure: Task = {
cancel in
if let internalClosure = closure {
if (cancel == false) {
DispatchQueue.global(qos: .userInitiated).async(execute: internalClosure);
}
}
closure = nil
result = nil
}
result = delayedClosure
dispatch_later {
if let delayedClosure = result {
delayedClosure(false)
}
}
return result;
}
func cancel(task:Task?) {
task?(true)
}

调用方法还是和之前一样

1
delay(2) { print("2 秒后输出") }

想要取消的话,我们可以先保留一个对 Task 的引用,然后调用 cancel:

1
2
3
4
5
let task = delay(5) { print("拨打 110") }
// 仔细想一想..
// 还是取消为妙..
cancel(task)