我正在创建一个双重链接的脚本列表(MSScript
s),它们应该有自己的run()
实现,并且当它们调用下一个脚本(rscript
)时他们准备好了。我想创建的一个脚本只是一个延迟。它看起来像这样:
class DelayScript : MSScript
{
var delay = 0.0
override func run() {
let delay = self.delay * Double(NSEC_PER_SEC)
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
let weakSelf = self
dispatch_after(time, dispatch_get_main_queue()) {
weakSelf.rscript?.run()
Void.self
}
}
init(delay: Double) {
super.init()
self.delay = delay
}
}
rscript
是下一个要运行的脚本。问题是如果我删除dispatch_after的最后一行,它就不会编译,那是因为the changed return type of run()
from optional chaining。我随机决定插入Void.self
并修复了问题,但我不明白为什么。
这是Void.self
是什么,它是正确的解决方案吗?
答案 0 :(得分:3)
可选的链接包装右侧的结果在可选内部。因此,如果run()
返回T
,则x?.run()
会返回T?
。由于run()
返回Void
(a.k.a。()
),这意味着整个可选链接表达式的类型为Void?
(或()?
)。
当闭包只有一行时,隐式返回该行的内容。所以如果你只有那一行,那就好像你写了return weakSelf.rscript?.run()
。因此,您返回的类型为Void?
,但dispatch_async
需要一个返回Void
的函数。所以他们不匹配。
一种解决方案是添加另一行显式不返回任何内容:
dispatch_after(time, dispatch_get_main_queue()) {
weakSelf.rscript?.run()
return
}